AA Applied Algorithms

Heapsort

Sort an array using a binary heap — O(N log N) and in-place.

Intuition

The big idea in one sentence

Rearrange the array so it behaves like a tree where every parent is bigger than its children — now the biggest element is at the top. Swap it with the last element, "forget" that last position, and repeat with what's left.

Heapsort solves the sorting problem in two phases:

  1. Build a max-heap out of the array (so largest is at index 1).
  2. Repeatedly swap the root with the last unsorted element, shrink the heap by 1, and re-heapify.

The heap property

A max-heap is an array we interpret as a binary tree where every parent ≥ its children. The array layout (using 1-indexing):

Example: the array [100, 19, 36, 17, 3, 25, 1, 2, 7] is a valid max-heap. Visually:

100 19 36 17 3 25 1 2 7

Notice: 100 ≥ 19 and 36; 19 ≥ 17 and 3; 36 ≥ 25 and 1; 17 ≥ 2 and 7. ✓

Key consequence: the max value of the heap is always at index 1 — getting the max is O(1).

The algorithm

HEAPSORT(table[1..N]):
    BuildHeap(table, N)              // turn array into a max-heap
    for i = N down to 2:
        swap table[1] and table[i]   // largest element to end
        BuildHeap(table, i-1)        // re-heapify on the shrunk range

BuildHeap(table, size):
    // ensure every parent is ≥ its children
    for index = size down to 1:
        leftChild  = 2 * index
        rightChild = 2 * index + 1
        biggest    = index
        if leftChild  <= size and table[leftChild]  > table[biggest]: biggest = leftChild
        if rightChild <= size and table[rightChild] > table[biggest]: biggest = rightChild
        if biggest != index:
            swap table[index] and table[biggest]
            // (and continue sifting down — done iteratively in practice)

Interactive demo

idle

Step-by-step walkthrough

Starting array: 25, 17, 36, 2, 3, 100, 1, 19, 7

Phase 1 — Build the max-heap

Walk from the last index back to 1 and sift each node down. After BuildHeap:

[100, 19, 36, 17, 3, 25, 1, 2, 7]    ✓ heap property holds

Phase 2 — Repeatedly swap and shrink

Step  Array (sorted suffix in italics)
1     swap 100 ↔ 7  → [7, 19, 36, 17, 3, 25, 1, 2, 100]
1.5   re-heapify    → [36, 19, 25, 17, 3, 7, 1, 2, 100]
2     swap 36 ↔ 2   → [2, 19, 25, 17, 3, 7, 1, 36, 100]
2.5   re-heapify    → [25, 19, 7, 17, 3, 2, 1, 36, 100]
3     swap 25 ↔ 1   → [1, 19, 7, 17, 3, 2, 25, 36, 100]
3.5   re-heapify    → [19, 17, 7, 1, 3, 2, 25, 36, 100]
…     continue until everything is sorted
final               → [1, 2, 3, 7, 17, 19, 25, 36, 100]

Complexity

StepCost
BuildHeap (once)O(N)
Each re-heapify after swapO(log N)
We do N−1 swapsO(N log N)
TotalO(N log N)

Exam tips

Things they love to ask

  • "Draw the heap" from an array — remember 1-indexed, parent at i/2.
  • "Apply BuildHeap to this array" — sift from N down to 1, swap parent with the larger child if needed.
  • "Trace heapsort step-by-step" — show array after each swap-and-reheapify.
  • "Why O(N log N)?" — N swaps, each followed by sifting down which is at most log N deep (tree height).