Selection Sort
Learn how selection sort finds the minimum value in an unsorted region, swaps it into place, and grows a sorted region from left to right.
Introduction
Selection sort is an in-place comparison sorting algorithm that divides the input array into a sorted and an unsorted region, repeatedly selecting the smallest element from the unsorted region and moving it to the end of the sorted region.
The Core Idea
Selection sort repeatedly finds the smallest value in the unsorted part of an array and places it at the next sorted position.
Track the Minimum
Start at the first position. Treat its value as the current minimum, then scan every value to its right.
- If a smaller value appears, update the minimum.
- After the scan finishes, swap the minimum with the value at the starting position.
After this swap, the first position is correct: no value in the array is smaller than 1.
Shrink the Unsorted Region
Once the minimum is placed, it belongs to the sorted region and does not need to be checked again.
[1 | 3, 4, 5, 2]
sorted unsortedNow repeat the process beginning at the first unsorted position:
- Find the minimum in the unsorted region.
- Swap it into that region's first position.
- Move the boundary one position right.
Key pattern
Each pass grows the sorted region by one value and shrinks the unsorted region by one position.
Selection sort outline
for each position from left to right:
find the minimum value from this position to the end
swap that minimum into the current positionThe final position needs no work: when every earlier minimum has been placed, the remaining value is already in the correct position.
Implementing Selection Sort
Selection sort repeatedly finds the smallest value in the unsorted part of a list and moves it into the next sorted position.
Nested-loop structure
Use two loops:
- The outer loop (
i) chooses the position to fill, moving from the start to the second-to-last element. - The inner loop (
j) searches the remaining unsorted values for the smallest one. - Swap that smallest value into the chosen position
i.
Implementation
function selectionSort(array) {
for (let i = 0; i < array.length - 1; i++) {
let smallestIndex = i;
for (let j = i + 1; j < array.length; j++) {
if (array[j] < array[smallestIndex]) {
smallestIndex = j;
}
}
// Swap if a smaller element was found
if (smallestIndex !== i) {
const temporary = array[i];
array[i] = array[smallestIndex];
array[smallestIndex] = temporary;
}
}
return array;
}Swap logic
A swap exchanges the value at the current position with the smallest value found by the inner loop.
If smallestIndex is already i, the current value is already the smallest remaining value, so no meaningful move is needed (avoiding a redundant self-swap).
Examples
Basic usage
const numbers = [29, 10, 14, 37, 13];
console.log(selectionSort(numbers)); // [10, 13, 14, 29, 37]
const fruits = ["banana", "apple", "orange", "grape"];
console.log(selectionSort(fruits)); // ["apple", "banana", "grape", "orange"]Step-by-step trace
For the array [29, 10, 14, 37, 13]:
| Pass | Unsorted region | Minimum found | Swap performed | Array state after pass |
|---|---|---|---|---|
Pass 1 (i = 0) | [29, 10, 14, 37, 13] | 10 (index 1) | Swap index 0 and 1 | [10 | 29, 14, 37, 13] |
Pass 2 (i = 1) | [29, 14, 37, 13] | 13 (index 4) | Swap index 1 and 4 | [10, 13 | 14, 37, 29] |
Pass 3 (i = 2) | [14, 37, 29] | 14 (index 2) | None (smallestIndex === i) | [10, 13, 14 | 37, 29] |
Pass 4 (i = 3) | [37, 29] | 29 (index 4) | Swap index 3 and 4 | [10, 13, 14, 29 | 37] |
Array is fully sorted: [10, 13, 14, 29, 37].
Evaluating Selection Sort
The inner loop scans the remaining unsorted values for every outer-loop position. Regardless of the initial arrangement of data, selection sort always scans the entire unsorted partition to ensure it has found the absolute minimum.
Complexity analysis
| Case | Time complexity | Why |
|---|---|---|
| Best Case | O(n²) | Must scan through the entire unsorted region even if already sorted. |
| Average Case | O(n²) | Nested loops perform total comparisons. |
| Worst Case | O(n²) | Reverse sorted input requires scanning every pair on every pass. |
| Space Complexity | O(1) | Sorts in-place with constant auxiliary memory. |
Comparison with Bubble Sort
| Property | Bubble Sort | Selection Sort |
|---|---|---|
| Main action | Push maximum to end via adjacent swaps | Find minimum in unsorted region, swap once |
| Comparisons | ||
| Swaps | Up to swaps | At most swaps (at most 1 swap per pass) |
| Best case | (with early-stop check) | (always scans all elements) |
Key trade-off
Selection sort still takes O(n²) time, but it can use significantly fewer swaps than bubble sort because it selects one smallest value for each position rather than repeatedly swapping neighboring values. This makes selection sort advantageous in environments where memory writes or swaps are costly.
Key Takeaways
- Find and Place Minimum: Selection sort operates by scanning the unsorted region to find the smallest value, then placing it at the beginning of that region.
- Growing Sorted Region: The array is partitioned into a sorted prefix on the left and an unsorted suffix on the right; each pass increases the sorted prefix by one element.
- Minimal Swaps: Unlike bubble sort, selection sort performs at most one swap per outer-loop pass ( total swaps), minimizing costly write operations.
- Consistent Quadratic Time: Because it must scan all remaining elements to confirm the minimum, selection sort always runs in time across best, average, and worst cases.
- In-Place: Selection sort operates directly on the input array, requiring only constant extra space.