Selection sort
Selection sort grows a sorted prefix by repeatedly finding the minimum of the unsorted part and swapping it into place. It always makes n(n-1)/2 comparisons but at most n - 1 swaps.
Learning goals
- Trace selection sort and its minimum search
- Explain why it makes at most n - 1 swaps
- Show with an example why it is not stable
Prerequisites
Find minimum
For each position i, scan arr[i..n-1] to find the index of the smallest value, then swap it into position i.
Invariant: after iteration i, arr[0..i] holds the i + 1 smallest values in sorted order, and they never move again.
Selection sort
Interactive · edit the inputint[] arr · length 7
Grow a sorted prefix by repeatedly selecting the minimum of the unsorted part.
1public static void selectionSort(int[] arr) {2int n = arr.length;3for (int i = 0; i < n - 1; i++) {4int min = i;5for (int j = i + 1; j < n; j++) {6if (arr[j] < arr[min]) {7min = j;8}9}10if (min != i) {11int tmp = arr[i];12arr[i] = arr[min];13arr[min] = tmp;14}15}16}
Live state
n
7
Execution trace (dry run table)Show 48 stepsHide
| Step | Line | State | What happens |
|---|---|---|---|
| 1 | L2 | n=7 | Grow a sorted prefix by repeatedly selecting the minimum of the unsorted part. |
| 2 | L4 | i=0 min=0 | Assume arr[0] = 38 is the minimum of [0..6]. |
| 3 | L6 | i=0 min=0 j=1 | Smaller value found. |
| 4 | L7 | i=0 min=1 j=1 | min = 1. |
| 5 | L6 | i=0 min=1 j=2 | Not smaller. |
| 6 | L6 | i=0 min=1 j=3 | Smaller value found. |
| 7 | L7 | i=0 min=3 j=3 | min = 3. |
| 8 | L6 | i=0 min=3 j=4 | Not smaller. |
| 9 | L6 | i=0 min=3 j=5 | Not smaller. |
| 10 | L6 | i=0 min=3 j=6 | Not smaller. |
| 11 | L10 | i=0 min=3 | The minimum 3 belongs at index 0. |
| 12 | L12 | i=0 min=3 | Swap arr[0] and arr[3]. A long-distance swap like this can reorder equal keys, so selection sort is not stable. |
| 13 | L4 | i=1 min=1 | Assume arr[1] = 27 is the minimum of [1..6]. |
| 14 | L6 | i=1 min=1 j=2 | Not smaller. |
| 15 | L6 | i=1 min=1 j=3 | Not smaller. |
| 16 | L6 | i=1 min=1 j=4 | Smaller value found. |
| 17 | L7 | i=1 min=4 j=4 | min = 4. |
| 18 | L6 | i=1 min=4 j=5 | Not smaller. |
| 19 | L6 | i=1 min=4 j=6 | Not smaller. |
| 20 | L10 | i=1 min=4 | The minimum 9 belongs at index 1. |
| 21 | L12 | i=1 min=4 | Swap arr[1] and arr[4]. A long-distance swap like this can reorder equal keys, so selection sort is not stable. |
| 22 | L4 | i=2 min=2 | Assume arr[2] = 43 is the minimum of [2..6]. |
| 23 | L6 | i=2 min=2 j=3 | Smaller value found. |
| 24 | L7 | i=2 min=3 j=3 | min = 3. |
| 25 | L6 | i=2 min=3 j=4 | Smaller value found. |
| 26 | L7 | i=2 min=4 j=4 | min = 4. |
| 27 | L6 | i=2 min=4 j=5 | Not smaller. |
| 28 | L6 | i=2 min=4 j=6 | Smaller value found. |
| 29 | L7 | i=2 min=6 j=6 | min = 6. |
| 30 | L10 | i=2 min=6 | The minimum 10 belongs at index 2. |
| 31 | L12 | i=2 min=6 | Swap arr[2] and arr[6]. A long-distance swap like this can reorder equal keys, so selection sort is not stable. |
| 32 | L4 | i=3 min=3 | Assume arr[3] = 38 is the minimum of [3..6]. |
| 33 | L6 | i=3 min=3 j=4 | Smaller value found. |
| 34 | L7 | i=3 min=4 j=4 | min = 4. |
| 35 | L6 | i=3 min=4 j=5 | Not smaller. |
| 36 | L6 | i=3 min=4 j=6 | Not smaller. |
| 37 | L10 | i=3 min=4 | The minimum 27 belongs at index 3. |
| 38 | L12 | i=3 min=4 | Swap arr[3] and arr[4]. A long-distance swap like this can reorder equal keys, so selection sort is not stable. |
| 39 | L4 | i=4 min=4 | Assume arr[4] = 38 is the minimum of [4..6]. |
| 40 | L6 | i=4 min=4 j=5 | Not smaller. |
| 41 | L6 | i=4 min=4 j=6 | Not smaller. |
| 42 | L10 | i=4 min=4 | arr[4] is already the minimum. No swap: selection sort does at most n - 1 swaps. |
| 43 | L4 | i=5 min=5 | Assume arr[5] = 82 is the minimum of [5..6]. |
| 44 | L6 | i=5 min=5 j=6 | Smaller value found. |
| 45 | L7 | i=5 min=6 j=6 | min = 6. |
| 46 | L10 | i=5 min=6 | The minimum 43 belongs at index 5. |
| 47 | L12 | i=5 min=6 | Swap arr[5] and arr[6]. A long-distance swap like this can reorder equal keys, so selection sort is not stable. |
| 48 | L16 | Sorted with 21 comparisons, 5 swaps. The comparison count is always n(n-1)/2 = 21. |
Minimum swaps
Selection sort performs at most one swap per position, so at most n - 1 swaps in total, no matter the input. Bubble and insertion sort can need up to n(n-1)/2 moves.
That makes it a reasonable choice when writes are far more expensive than reads, such as flash memory with limited write cycles. Cycle sort (17.05) goes further and writes each element at most once.
Instability
The long-distance swap can jump an element over an equal key. Example: [4a, 3, 4b, 1]. The first step swaps 4a with 1, giving [1, 3, 4b, 4a], and 4a now comes after 4b.
A stable variant inserts the minimum by shifting instead of swapping, but that costs O(n²) moves and loses selection sort's one advantage.
Stability: what happens to equal keys?
InteractiveInput · letters show original order of equal keys
Insertion sort
Bubble sort
Selection sort
Shell sort
Dry run
Sorting [64, 25, 12, 22, 11].
- Comparisons: 4 + 3 + 2 + 1 = 10 = n(n-1)/2. Swaps: 3.
| i | Minimum of arr[i..] | Swap | Array after |
|---|---|---|---|
| 0 | 11 at index 4 | arr[0] ↔ arr[4] | [11, 25, 12, 22, 64] |
| 1 | 12 at index 2 | arr[1] ↔ arr[2] | [11, 12, 25, 22, 64] |
| 2 | 22 at index 3 | arr[2] ↔ arr[3] | [11, 12, 22, 25, 64] |
| 3 | 25 at index 3 | none | [11, 12, 22, 25, 64] |
Complexity
The inner loop always runs to the end, so comparisons are exactly n(n-1)/2 for every input: sorted, reverse or random. Selection sort is not adaptive.
Best
O(n²)
Average
O(n²)
Worst
O(n²)
Space
O(1)
Practice ladder
Now try it yourself
Easy
- Selection sort descending by selecting the maximum
- Count comparisons for n = 10
Medium
- Double-ended selection sort: place both the min and the max each pass
- Stable selection sort using shifting
Advanced
- Find the k smallest values using k selection passes and analyse the cost
- Compute the minimum swaps to sort a permutation using cycles
Key takeaways
- Always n(n-1)/2 comparisons, at most n - 1 swaps.
- Not adaptive and not stable.
- Useful when writes are expensive; otherwise insertion sort is usually better.