Selection Sort Visualization — Step by Step

Finds the minimum element and places it at the beginning, repeating for each position.

SortingbeginnerUpdated

// quick answer

Selection Sort is a sorting algorithm that runs in O(n²) time on average with O(1) space. Finds the minimum element and places it at the beginning, repeating for each position.

How Selection Sort Works

Selection Sort divides the array into a sorted and unsorted region. It repeatedly scans the unsorted region to find the minimum element, then swaps it with the first unsorted position. Simple but inefficient for large lists.

Selection Sort Step by Step

Two regions, one boundary

Picture the array split by an invisible line: everything left of the line is sorted and final, everything right of it is untouched. At the start, the line sits before index 0 — nothing is sorted yet. Each pass of Selection Sort does exactly one job: find the smallest value in the unsorted region and move it to the position just right of the line, then advance the line by one. After n−1 passes the line has swept the whole array and the sort is done. Unlike Bubble Sort, nothing left of the line is ever touched again.

Step 1: Scan for the minimum

Take [5, 2, 8, 1]. Pass one assumes the first unsorted element, 5, is the minimum, then scans right updating its guess: 2 is smaller (new minimum), 8 is not, 1 is smaller (new minimum). The scan always runs to the very end of the array — there is no way to know 1 is the true minimum without checking everything after it. That full scan happens every pass regardless of the data, which is why Selection Sort has no best case: even a sorted array costs the full n(n−1)/2 comparisons.

Step 2: One swap, one locked position

With the minimum found at index 3, Selection Sort makes a single swap: 5 and 1 trade places, giving [1, 2, 8, 5], and index 0 is locked forever. Pass two scans [2, 8, 5], finds 2 already in place, and — as in this implementation — skips the swap entirely when the minimum hasn't moved. Pass three scans [8, 5], swaps to [1, 2, 5, 8], and the last element is sorted by elimination. Total damage: at most n−1 swaps, the fewest of any comparison sort here.

Why so few writes — and why that matters

Selection Sort separates *finding* from *moving*. All the O(n²) work happens in comparisons, which are reads; each element is then written to its final home in one hop. Compare that with Bubble Sort, where a far-from-home element generates a long trail of swap writes. On hardware where writes are costly or physically limited — classic examples are EEPROM and flash memory — minimizing writes is the whole game, and this is the one niche where Selection Sort genuinely earns its keep.

The catch: instability

That long-distance swap has a side effect. Sort [3a, 3b, 1] (two equal 3s, tagged by original position): the minimum is 1, so it swaps with 3a — producing [1, 3b, 3a]. The equal elements have changed relative order, which makes Selection Sort unstable. If you are sorting records by one key while preserving an earlier ordering (say, sorting by grade while keeping names alphabetical), stability matters, and you should reach for Insertion Sort or Merge Sort instead.

Time & Space Complexity

Best CaseAverage CaseWorst CaseSpace
O(n²)O(n²)O(n²)O(1)

Selection Sort Pseudocode

function selectionSort(arr):
  for i = 0 to n-2:
    minIdx = i
    for j = i+1 to n-1:
      if arr[j] < arr[minIdx]:
        minIdx = j
    swap(arr[i], arr[minIdx])
    mark arr[i] as sorted

Press play in the visualizer above to watch each line execute with live highlighting.

Selection SortCode in JavaScript, Python & Java

JavaScript

function selectionSort(arr) {
  const n = arr.length;
  for (let i = 0; i < n - 1; i++) {
    let minIdx = i;
    for (let j = i + 1; j < n; j++) {
      if (arr[j] < arr[minIdx]) minIdx = j;
    }
    if (minIdx !== i) {
      [arr[i], arr[minIdx]] = [arr[minIdx], arr[i]];
    }
  }
  return arr;
}

Python

def selection_sort(arr):
    n = len(arr)
    for i in range(n - 1):
        min_idx = i
        for j in range(i + 1, n):
            if arr[j] < arr[min_idx]:
                min_idx = j
        if min_idx != i:  # at most one swap per pass
            arr[i], arr[min_idx] = arr[min_idx], arr[i]
    return arr

Java

public static void selectionSort(int[] arr) {
    int n = arr.length;
    for (int i = 0; i < n - 1; i++) {
        int minIdx = i;
        for (int j = i + 1; j < n; j++) {
            if (arr[j] < arr[minIdx]) minIdx = j;
        }
        if (minIdx != i) { // at most one swap per pass
            int tmp = arr[i];
            arr[i] = arr[minIdx];
            arr[minIdx] = tmp;
        }
    }
}

When to Use Selection Sort

  • When writes are expensive — at most n−1 swaps is the smallest write count among the simple sorts, valuable on flash/EEPROM or when each move triggers costly side effects.
  • When memory is extremely tight — it is in-place, O(1) extra space, with dead-simple control flow that is easy to verify on embedded targets.
  • Teaching invariants — the sorted-region boundary is the cleanest possible illustration of a loop invariant, and its total predictability (same work on every input) makes complexity analysis honest.
  • Avoid it on nearly-sorted data — it cannot exploit existing order at all; it scans everything every pass, while Insertion Sort finishes the same input in near-linear time.
  • Avoid it when stability matters — the long-range swap reorders equal elements; use a stable sort like Merge Sort instead.
  • See the trade-off live: race it against Insertion Sort and watch Selection Sort do fewer moves but never fewer comparisons.

Selection Sort — Frequently Asked Questions

Is Selection Sort stable?

No, the standard array version is not stable. When the minimum is swapped into place it can jump over an element equal to the one it displaces, changing the relative order of equal values. For example, sorting the sequence 3, 3, 1 moves the first 3 behind the second. A stable variant exists that inserts by shifting instead of swapping, but it loses the low-write advantage.

What is the time complexity of Selection Sort?

O(n²) in every case — best, average, and worst. Each pass must scan the entire unsorted region to be certain it found the minimum, so it performs n(n−1)/2 comparisons even on already-sorted input. That makes it non-adaptive: existing order gives no speedup. Space complexity is O(1), and it performs at most n−1 swaps.

Why does Selection Sort make so few swaps?

Because it fully separates searching from moving. It first spends a whole pass identifying exactly which element belongs in the next position, then performs a single swap to put it there. Every element is written to its final location at most once via a swap, giving at most n−1 swaps total — compared with up to n(n−1)/2 for bubble sort on reversed input.

Selection Sort vs Bubble Sort — which is better?

Selection Sort usually wins on random data because it makes dramatically fewer swaps, while Bubble Sort wins on nearly-sorted data because its early-exit pass finishes in O(n) where Selection Sort still burns the full O(n²) comparisons. Bubble Sort is also stable; Selection Sort is not. For general use, both lose to insertion sort, which is faster in practice and stable.

Is Selection Sort used in real life?

Rarely, but it has a genuine niche: environments where writes are far more expensive than reads, such as flash or EEPROM memory, because it guarantees at most n−1 swaps. Its cousin heapsort is essentially Selection Sort with a heap replacing the linear scan, turning the O(n) minimum search into O(log n) — and heapsort is widely used.

Compare Selection Sort

Related Algorithms

References & Further Reading