If you are in Year 3 of the liceo scientifico (Italian science-focused high school), applied sciences option, and in October in computer science you have finished (or are finishing) loops and arrays, sorting algorithms are the next step: they usually arrive between October and November, and the test that covers them falls six to nine weeks away. There is time to really understand them, instead of learning them by heart. If you are missing the basics on arrays, start from loops and arrays; for the cost of algorithms in general there is complexity and big-O notation, here I only touch on it intuitively.
The idea in one line each
We have to sort an array in increasing order. Three strategies, all based on comparisons and swaps:
- Bubble sort: compares adjacent pairs and swaps them if they are in the wrong order. On each pass the largest value “rises” to the end, like a bubble.
- Selection sort: on each pass it looks for the minimum of the part not yet sorted and moves it to the first free position.
- Insertion sort: keeps the left part sorted and inserts, one at a time, the next element in the right place, like when you sort the cards in your hand.
A trace on an array of 6 elements
We will always use . Hand traces are what you are asked for in a test, so read them with a pencil in your hand.
Bubble sort
Pass 1 (5 comparisons): swap → ; swap → ; no; swap → ; swap → . The 6 is in its final place.
Pass 2 (4 comparisons): no; no; swap; swap → .
Pass 3 (3 comparisons): no; swap; swap → .
Pass 4 (2 comparisons): swap → ; no.
Pass 5 (1 comparison): no. Total: 15 comparisons and 9 swaps.
Selection sort
- : the minimum of the whole array is 1 (position 4); swap with the 5 → .
- : the minimum of is 2, already in place; no swap.
- : the minimum of is 3; swap with the 4 → .
- : the minimum of is 4; swap with the 6 → .
- : the minimum of is 5, already in place.
Total: 15 comparisons and 3 swaps (at most ).
Insertion sort
Here elements are “shifted” to the right to make room, then the key is inserted.
- : the 5 is larger, it shifts → (1 shift).
- : the 5 shifts, the 2 does not → (1).
- : the 5 is not larger than 6, so it stays where it is (0).
- : 6, 5, 4, 2 shift, then 1 goes to the front → (4).
- : 6, 5, 4 shift, the 2 does not → (3).
Total: 12 comparisons and 9 shifts. The 9 is no accident: it coincides with the number of swaps in bubble sort, because both remove the inversions one by one, that is, the pairs in which a larger element comes before a smaller one. In there are .
Pseudocode and Python
Bubble sort, in pseudocode:
for i from 0 to n-2:
for j from 0 to n-2-i:
if a[j] > a[j+1]:
tmp = a[j]
a[j] = a[j+1]
a[j+1] = tmp
In Python the swap can be written in one line, but understanding the version with tmp matters in all the other languages:
def bubble_sort(a):
n = len(a)
for i in range(n - 1):
for j in range(n - 1 - i):
if a[j] > a[j + 1]:
a[j], a[j + 1] = a[j + 1], a[j]
def selection_sort(a):
n = len(a)
for i in range(n - 1):
m = i
for j in range(i + 1, n):
if a[j] < a[m]:
m = j
a[i], a[m] = a[m], a[i]
def insertion_sort(a):
for i in range(1, len(a)):
k = a[i]
j = i - 1
while j >= 0 and a[j] > k:
a[j + 1] = a[j]
j -= 1
a[j + 1] = k
When you pass an array to a function that modifies it, remember how parameter passing works: I talk about it in pass by value and by reference.
Why they are O(n²) and which one to choose
All three have two nested loops. The outer loop runs about times and the inner one, on average, about : the comparisons are of the order of
For that makes 15, which is exactly the number we counted. If you double the comparisons become about four times as many: that is the intuitive meaning of .
Which to choose:
| Algorithm | Comparisons | Swaps or shifts | When it is worth it |
|---|---|---|---|
| bubble | many | almost never; useful for learning | |
| selection | always | at most | when writing is expensive |
| insertion | from to | equal to the inversions | small or almost sorted arrays |
In bubble sort you can add a check: if in a pass no swap happens, the array is already sorted and you stop. On an already sorted array it makes only comparisons.
The mistakes I see most
Wrong loop limits. In bubble sort the inner index goes up to (in Python range(n-1-i)) because inside the loop a[j+1] is read: with a limit one too high you run off the end of the array. In the same way the outer loop must not reach . In selection sort the inner loop starts from , not from , otherwise you compare the element with itself.
Swapping without a temporary variable. Writing a[j] = a[j+1] and straight after a[j+1] = a[j] copies the same value twice and the original value of a[j] is lost.
Confusing selection and bubble. Selection sort first looks for the minimum and then swaps once; bubble swaps during the scan.
Forgetting the shifting in insertion sort. If you don’t save the key before shifting the elements, you overwrite it.
Three worked exercises
1. The worst case of bubble sort
Count the comparisons and swaps of bubble sort on .
Pass 1: , , are three comparisons and three swaps → . Pass 2: and , two swaps → . Pass 3: , one swap → . Total: comparisons and swaps, that is, all 6 pairs are inversions. With the already sorted array and the early-exit check, on the other hand, 3 comparisons and 0 swaps.
2. How fast the cost grows
How many comparisons are needed to sort 10, 100 and 1000 elements with selection sort? And 2000?
For 2000: , about 4 times the 499,500 from before: doubling makes the cost quadruple. Multiplying by 10 multiplies the comparisons by about 100.
3. Find the mistake
This bubble sort in a language without multiple assignment has two mistakes. Which ones?
for j from 0 to n-1-i:
if a[j] > a[j+1]:
a[j] = a[j+1]
a[j+1] = a[j]
First mistake: with up to , when you reach and read a[n], outside the array; the correct limit is . Second mistake: the swap. With , the first assignment gives and the second leaves it as : the 7 has vanished. You need tmp = a[j] before the first assignment and a[j+1] = tmp at the end.
Test yourself
To train on timed reasoning you can use the practice tests for high school. There is not yet a dedicated practice test for computer science: the questions you find cover maths and physics. A good way to prepare is to redo the three traces without looking, changing the array. More resources are on the computer science page; if you need a hand, I give 1-to-1 online tutoring and you can start with a free introductory call. Close to this topic there is also recursion, which usually follows sorting.