Lesson 5: Stability and insertion sort

Two questions every sharp learner asks: "does it keep ties in order?" and "what should I use instead?"

~12 minutes. Builds on Lesson 4.

Stability

A sort is stable when equal keys keep their original relative order. Bubble sort is stable because it only swaps when a[j] > a[j + 1], strictly. Two equal neighbours never swap, so they can never pass each other.[1]

type Row = { name: string; age: number };
const rows: Row[] = [
  { name: 'Ana', age: 30 }, { name: 'Bo', age: 25 }, { name: 'Cy', age: 30 },
];
// sort by age with a[j].age > a[j+1].age  ->  Bo, Ana, Cy  (Ana still before Cy)
// change > to >=                          ->  Bo, Cy, Ana  (stability lost)
Teaching tip: change > to >= live and rerun. One character breaks stability. Learners remember the demo, not the definition.

Insertion sort, the honest sibling

Insertion sort also runs O(n²) worst case and O(n) on sorted input, and is also stable. Yet it is roughly 5x faster than bubble sort in practice.[1] Why: bubble sort does a full swap (three writes) for every inversion; insertion sort shifts elements with one write each and places the key once.[2]

function insertionSort(a: number[]): number[] {
  for (let i = 1; i < a.length; i++) {
    const key = a[i];
    let j = i - 1;
    while (j >= 0 && a[j] > key) { a[j + 1] = a[j]; j--; }
    a[j + 1] = key;
  }
  return a;
}
BubbleInsertion
Worst / bestO(n²) / O(n) with flagO(n²) / O(n)
StableYesYes
Writes per inversion3 (swap)1 (shift)
What each pass fixesLargest of the prefix, to the endGrows a sorted prefix by one
Real useTeaching onlySmall n, base case of hybrid sorts

Retrieval practice

Primary source

Sedgewick and Wayne, Elementary Sorts: slides on insertion sort invariants and why it wins among simple sorts.

Anything unclear? Ask your teaching agent - it wrote this lesson and can go deeper on any point.