1. Home
  2. Design & Analysis of Algorithms
  3. Selection Sort

Selection Sort

Find the smallest value, swap it to the front, repeat. Always O(n²) comparisons, but never more than n − 1 swaps.

Interactive 3DBeginner8 min readDAAUpdated

Drag to rotate · Right-drag to pan · Click, then scroll to zoom · Space play · ←→ step

What's happening

Pseudocode

    Try this in the 3D model

    • Follow the pink min tag during one pass. How many times does it move before the swap?
    • Load Already sorted. Count the comparisons. Did selection sort finish any faster than on random data?
    • Compare the number of swaps here with Bubble Sort on the same numbers.
    • Type 4, 4, 1 and watch which 4 ends up first. That shows why selection sort is not stable.

    The idea

    Imagine lining up students by height. You scan the whole group, find the shortest student, and put them first. Then you scan the rest, find the next shortest, and put them second. You keep going until everyone is in place.

    Selection sort does exactly this:

    1. Look at the unsorted part of the array and select the smallest value.
    2. Swap it with the first element of the unsorted part.
    3. That position is now final, so the sorted part grows by one.
    4. Repeat until the unsorted part has only one element left.

    In the 3D model, the pink min tag jumps every time a smaller value is found. At the end of each pass, one long swap puts the minimum into its final green position.

    Step by step example

    Sorting [64, 25, 12, 22, 11]:

    Pass Smallest in unsorted part Swap Array after the pass
    1 11 64 ↔ 11 [11] 25 12 22 64
    2 12 25 ↔ 12 [11, 12] 25 22 64
    3 22 25 ↔ 22 [11, 12, 22] 25 64
    4 25 none (already in place) [11, 12, 22, 25, 64]

    Four passes, 4 + 3 + 2 + 1 = 10 comparisons and only 3 swaps.

    Code

    def selection_sort(a):
        n = len(a)
        for i in range(n - 1):
            m = i                          # index of the smallest so far
            for j in range(i + 1, n):
                if a[j] < a[m]:
                    m = j
            a[i], a[m] = a[m], a[i]        # one swap per pass
        return a
    
    print(selection_sort([64, 25, 12, 22, 11]))   # [11, 12, 22, 25, 64]
    #include <iostream>
    #include <vector>
    #include <utility>
    using namespace std;
    
    void selectionSort(vector<int>& a) {
        int n = a.size();
        for (int i = 0; i < n - 1; i++) {
            int m = i;
            for (int j = i + 1; j < n; j++)
                if (a[j] < a[m]) m = j;
            swap(a[i], a[m]);
        }
    }
    
    int main() {
        vector<int> a = {64, 25, 12, 22, 11};
        selectionSort(a);
        for (int x : a) cout << x << " ";   // 11 12 22 25 64
    }

    Analysis

    • Comparisons: pass 1 checks n − 1 values, pass 2 checks n − 2, and so on: (n−1) + (n−2) + … + 1 = n(n−1)/2. This number does not depend on the input, so the best, average and worst cases are all O(n²).
    • Swaps: at most one per pass, so at most n − 1. This is the smallest number of writes of any simple sort.
    • Space: O(1), because it sorts in place.

    Why it is not stable

    A stable sort keeps equal values in their original order. Selection sort’s long swap can break that. In [4a, 4b, 1], the first pass swaps 4a with 1, giving [1, 4b, 4a], and now 4b comes before 4a. (A stable version exists, but it shifts elements like insertion sort and loses the “few writes” advantage.)

    Selection vs bubble vs insertion sort

    Selection Bubble Insertion
    Comparisons Always n(n−1)/2 Up to n(n−1)/2 Up to n(n−1)/2
    Best case O(n²) O(n) with early exit O(n)
    Swaps / writes At most n − 1 Many Many shifts
    Stable ❌ ✅ ✅
    Adaptive (faster on sorted data) ❌ ✅ ✅

    Where is it used?

    • When writing is expensive but reading is cheap, for example flash memory that wears out with every write. Few swaps means few writes.
    • For very small arrays, where its simple code is good enough.
    • As an idea: heap sort is selection sort with a heap that finds the minimum (or maximum) in O(log n) instead of O(n), which brings the total down to O(n log n).

    Common mistakes

    • Swapping inside the inner loop every time a smaller value is found. That still sorts, but it makes many swaps and is no longer selection sort.
    • Remembering the value of the minimum instead of its index. You need the index to swap.
    • Starting the inner loop at j = i instead of j = i + 1. It works, but adds a useless comparison every pass.
    • Thinking selection sort gets faster on sorted input. It does not, because the scan always runs to the end.

    Complexity at a glance

    Case / operationTimeWhy
    Best case (already sorted)O(n²)It still scans the whole unsorted part every pass.
    Average caseO(n²)Exactly n(n−1)/2 comparisons.
    Worst caseO(n²)Same comparisons as the best case.
    SwapsO(n)At most one per pass, n − 1 in total.
    Extra spaceO(1)

    Quick check

    Test yourself — pick an answer to see if you got it.

    1. How many comparisons does selection sort make on an already sorted array of 6 elements?

    2. What is the largest number of swaps selection sort can make on n elements?

    3. Is selection sort stable?

    4. After i passes of selection sort, what is guaranteed?

    Saved only in this browser — no account needed.
    Spotted a mistake or a bug in the 3D model?

    Report a mistake

    in Selection Sort. Thank you — every report makes the lesson better for the next reader.

    We'll also include a link to the step of the 3D model you're on and your browser type, so we can reproduce it.