Build a max-heap from an unsorted array
Take an unsorted array of 7 numbers and transform it into a max-heap in O(n), running sift-down at each internal node from the deepest backward to the root.
concept: Heap Sort
Problem
Take the array
a = [3, 1, 6, 5, 2, 4, 8] # n = 7 and rearrange it in place into a max-heap. Show every step. Count the swaps.
Approach
The array is a tree. Index 's children are at and . Drawn out:
3 <- a[0]
/ \
1 6 <- a[1], a[2]
/ \ / \
5 2 4 8 <- a[3], a[4], a[5], a[6] We call sift_down at every internal node, starting from the deepest internal node and walking back to the root. With , the deepest internal node is at index . So we run sift-down at indices 2, 1, 0 in that order.
Why bottom-up? Sift-down needs both child subtrees to already be heaps. Going from the bottom up guarantees that — by the time we sift-down at index , both children's subtrees have already been processed.
Walkthrough
Index 2 holds 6. Children are a[5] = 4 and a[6] = 8.
Largest child: a[6] = 8. Is 8 > 6? Yes. Swap.
a = [3, 1, 8, 5, 2, 4, 6] Now sit at index 6. It's a leaf — no children inside the array. Sift-down terminates.
3
/ \
1 8
/ \ / \
5 2 4 6 Swaps so far: 1.
Index 1 holds 1. Children are a[3] = 5 and a[4] = 2.
Largest child: a[3] = 5. Is 5 > 1? Yes. Swap.
a = [3, 5, 8, 1, 2, 4, 6] Now sit at index 3. Leaf. Done.
3
/ \
5 8
/ \ / \
1 2 4 6 Swaps so far: 2.
Index 0 holds 3. Children are a[1] = 5 and a[2] = 8.
Largest child: a[2] = 8. Is 8 > 3? Yes. Swap.
a = [8, 5, 3, 1, 2, 4, 6] Now sit at index 2 (where the 3 now lives). Children are a[5] = 4 and a[6] = 6. Largest: 6. Is 6 > 3? Yes. Swap.
a = [8, 5, 6, 1, 2, 4, 3] Now sit at index 6. Leaf. Done.
Swaps so far: 4.
Final state
a = [8, 5, 6, 1, 2, 4, 3] 8
/ \
5 6
/ \ / \
1 2 4 3 Check the heap property at every parent–child pair: 8 ≥ 5, 8 ≥ 6, 5 ≥ 1, 5 ≥ 2, 6 ≥ 4, 6 ≥ 3. All good. is the max of the array.
a = [8, 5, 6, 1, 2, 4, 3]. 4 swaps total across 3 sift-down calls. Two of the calls did one swap each (cheap leaf-adjacent sifts), and the third call sifted two levels down.
Remarks
The "swap count" pattern here is exactly what makes build-heap surprisingly cheap. Half the internal nodes sit one level above the leaves and do at most 1 swap. A quarter sit two levels up and do at most 2. The total sum is geometric — it stays linear in , not like you might guess.
From here, heap sort proceeds by repeatedly swapping a[0] with the last element of the heap, shrinking the heap by one, and calling sift-down at the root. The max value lands in its sorted slot each round.