Skip to content

Selection sort

Find the smallest remaining value and swap it into the next place. It always makes n(n − 1)/2 comparisons, but at most n − 1 swaps.

Helps to know firstBubble sort

Helps to know first
This topic

First, the picture

Scan what is left for its smallest value, and swap it into the next place. Watch one swap per sweep.

Picking the smallest each time

Ten numbers; the smallest of the rest is swapped into place

void selection_sort(int *a, int n){    for (int i = 0; i < n - 1; i++) {        int m = i;        for (int j = i + 1; j < n; j++) {            comparisons++;            if (a[j] < a[m])                m = j;        }        if (m != i) {            int t = a[i];            a[i] = a[m];            a[m] = t;            swaps++;        }    }}

main has started: a has room for ten ints.

i
–
comparisons
0
swaps
0

Output

0.00 / 29.70 s
Describe this picture

Ten bars in a row, the cells of int a[10], each as tall as its value: 6 2 9 1 5 10 3 8 4 7, with the cell numbers 0 to 9 above them. The code pane beside the picture shows selection_sort, with the line about to run marked. The clip takes about 30 seconds. In each sweep, the marker j under the bars moves right one cell per comparison, its bar tinted, and the marker m over the bars stays on the smallest value seen so far, its bar tinted in a second colour; when a smaller bar turns up, m jumps to it. In the first sweep m starts on 6, jumps to 2 and then to 1. At the end of a sweep the smallest bar swaps into the next place, sliding past the bar that was there, or, when it is already there, nothing moves. The placed bars on the left grey, one per sweep. Under the picture are one sentence on the current step and the readouts “i”, “comparisons” and “swaps”, which end at 45 and 6. The transport plays and pauses, steps one beat back or forward, and scrubs; a paused step is kept in the page address as selection-sort.step.

The smallest of the rest

Cell 0 should hold the smallest value. Scan the whole array for it, and swap it into cell 0. Cell 1 should hold the smallest of what is left: scan cells 1 to 9, and swap. Each sweep places one value for good, and the part still to scan shrinks by one cell.

Unlike bubble sort, nothing moves during a sweep. The scan only reads; one swap at the end does all the writing.

The code and its cost

void selection_sort(int *a, int n)
{
    for (int i = 0; i < n - 1; i++) {
        int m = i;
        for (int j = i + 1; j < n; j++) {
            comparisons++;
            if (a[j] < a[m])
                m = j;
        }
        if (m != i) {
            int t = a[i];
            a[i] = a[m];
            a[m] = t;
            swaps++;
        }
    }
}

m is the index of the smallest value seen so far in the sweep. After the inner loop it is the smallest of a[i] to a[n − 1], and the swap puts it in a[i]. The test m != i skips a swap that would exchange a cell with itself.

Counting the work

Sweep i compares a[m] with a[i + 1] to a[n − 1]: n − 1 − i comparisons. Together that is 9 + 8 + … + 1 = 45 for ten values, n(n − 1)/2 in general, for every input: the scan cannot know that the rest is sorted without looking at every value. On the house array the smallest is elsewhere at i = 0, 2, 3, 5, 6 and 8, and already in place at i = 1, 4 and 7, so selection.c prints 45 comparisons, 6 swaps.

There are at most n − 1 swaps, two writes each: at most 2(n − 1) writes to the array. That is its one strength.

Properties

Selection sort is in place. It is not adaptive: sorted input costs the same 45 comparisons. It is not stable: a swap carries a value over every cell between, and can jump it past an equal value, as the worked example shows.

Worked example

Two equal values. Sort 5a 5b 3 by value, where a and b only tell the two 5s apart. The first sweep finds 3 at cell 2 and swaps it with cell 0, which holds 5a: 3 5b 5a. The second sweep finds nothing smaller than 5b, so the order stays, and the two 5s have changed places. selection-extra.c sorts these three cards and prints 3c 5b 5a.

Writes on the house array. Selection sort writes 12 cells (6 swaps of two cells). Insertion sort, on the same array, makes 20 moves and writes each of the 9 values it inserts back once: 29 writes. Bubble sort writes 40 (20 swaps).

Two checks. How many comparisons for ten values already sorted? (45.) And how many swaps? (0, thanks to m != i.)

Where it’s used

Where writes cost more than reads. Some memories wear out with writing, or write far more slowly than they read; selection sort’s n − 1 swaps keep the writes to a minimum.

Tiny arrays, where its simple loop is enough.

A better way to find the smallest. Heapsort is selection sort with a heap to find the largest of the rest in log₂ n steps instead of a scan (Heapsort).

Reference card

Code or ideaMeaning
one sweepm = index of the smallest of a[i..n − 1]; swap a[i], a[m]
after sweep ia[0..i] holds the i + 1 smallest values, in order
comparisonsn(n − 1)/2, for every input
swapsat most n − 1 (with m != i)
in place, stable, adaptiveyes, no, no

Platform: C11, gcc on x86-64 Linux: int 4 bytes, pointers 8, little-endian. Addresses in the pictures are short stand-ins, by one rule for the whole course; sizes are the real ones.

End of the lesson

Where to go next.

New lessons by email

Are you 13 or over?

Accounts and email updates are for people aged 13 or over. We keep only your answer, never your date of birth.

Phasorium

Account

Sign inWith Google, GitHub or your email

Subjects

Site

Look