Skip to content

Stable Selection Sort

A stable variant of selection sort that preserves the relative order of equal elements by shifting instead of swapping.

Stable selection sort modifies selection sort to preserve the relative order of equal elements. Instead of swapping the minimum element into position, it removes the minimum and shifts the intervening elements right by one position.

This ensures stability at the cost of additional data movement.

Problem

Given a sequence AA of length nn, reorder it such that

A[0]A[1]A[n1] A[0] \le A[1] \le \cdots \le A[n-1]

and equal elements retain their original relative order.

Algorithm

For each position ii, find the minimum element in [i,n1][i, n-1]. Store it, shift all elements between ii and its position one step to the right, then insert the minimum at position ii.

stable_selection_sort(A):
    n = length(A)
    for i from 0 to n - 1:
        min_index = i
        for j from i + 1 to n - 1:
            if A[j] < A[min_index]:
                min_index = j

        key = A[min_index]

        while min_index > i:
            A[min_index] = A[min_index - 1]
            min_index = min_index - 1

        A[i] = key

Example

Let

A=[(4,a),(2,b),(2,c),(3,d)] A = [(4,a), (2,b), (2,c), (3,d)]

where the second component indicates original order.

Step 1:

Minimum is (2,b)(2,b)

Shift elements:

→ [(2,b), (4,a), (2,c), (3,d)]

Step 2:

Minimum in remaining is (2,c)(2,c)

→ [(2,b), (2,c), (4,a), (3,d)]

Final result:

[(2,b),(2,c),(3,d),(4,a)] [(2,b), (2,c), (3,d), (4,a)]

Relative order of equal keys is preserved.

Correctness

At each iteration, the smallest remaining element is inserted at position ii. Since elements are shifted rather than swapped, no equal elements change their relative order. The invariant that the prefix is sorted and stable holds throughout execution.

Complexity

casecomparisonstime
bestn(n1)2\frac{n(n-1)}{2}O(n2)O(n^2)
worstn(n1)2\frac{n(n-1)}{2}O(n2)O(n^2)
averagen(n1)2\frac{n(n-1)}{2}O(n2)O(n^2)

Shifting increases the number of assignments, but asymptotic time remains:

O(n2) O(n^2)

Space complexity:

O(1) O(1)

Properties

  • stable
  • in-place
  • more writes than standard selection sort

When to Use

This variant is useful when stability is required but selection sort’s structure is preferred, such as in constrained environments where auxiliary memory must remain constant.

Implementation

def stable_selection_sort(a):
    n = len(a)
    for i in range(n):
        min_idx = i
        for j in range(i + 1, n):
            if a[j] < a[min_idx]:
                min_idx = j

        key = a[min_idx]
        while min_idx > i:
            a[min_idx] = a[min_idx - 1]
            min_idx -= 1
        a[i] = key

    return a
func StableSelectionSort[T constraints.Ordered](a []T) {
    n := len(a)
    for i := 0; i < n; i++ {
        minIdx := i
        for j := i + 1; j < n; j++ {
            if a[j] < a[minIdx] {
                minIdx = j
            }
        }

        key := a[minIdx]
        for minIdx > i {
            a[minIdx] = a[minIdx-1]
            minIdx--
        }
        a[i] = key
    }
}