Heap Data Structure | Build-Heap + Extract-Max
Picture a class lining up tallest-first. The lazy way is to scan everyone, pull out the tallest, then scan the rest and pull out the next tallest, again and again. Heapsort does the same "keep grabbing the biggest" trick — but it organizes the crowd first so finding the biggest each time is almost free.
| Symbol | Meaning |
|---|---|
| n | Number of elements |
| h | Height of heap = ⌊log₂n⌋ |
| T_build | Cost of BUILD-MAX-HEAP |
| T_extract | Cost of n SIFT-DOWN operations |
❌ "BUILD-MAX-HEAP is O(n log n) because we call SIFT-DOWN n/2 times."
✅ Most calls are on short subtrees near the leaves. The total is bounded by the converging series Σ h/2^h = 2, giving O(n).
❌ "A max-heap is a sorted array."
✅ Max-heap only guarantees parent ≥ children. Siblings have no ordering. A[0] is maximum, but A[1] and A[2] are not necessarily in sorted order with each other.
❌ "Heapsort is always faster than Mergesort since it uses O(1) space."
✅ Heapsort is typically slower in practice due to cache misses. Mergesort with O(n) space often runs faster on modern hardware despite the extra memory.
❌ Building the heap by inserting elements one by one (O(n log n)) instead of using BUILD-MAX-HEAP (O(n)).
✅ Top-down insertion is valid but suboptimal. Bottom-up BUILD-MAX-HEAP exploits the fact that most sift-down operations are cheap near the leaves.
❌ Using 1-indexed arrays without adjusting child/parent formulas.
✅ 0-indexed: parent=(i-1)/2, left=2i+1, right=2i+2. 1-indexed: parent=i/2, left=2i, right=2i+1. Mixing these formulas is a common bug.
❌ Forgetting to decrease heap size after each extraction (treating the whole array as heap).
✅ After swapping A[0] with A[end], the heap size decreases by 1. SIFT-DOWN must be called with the new (reduced) heap size, not n.