Sorting · 17 / 19
Heap sort visualization
Heap sort arranges the array as a max-heap, then repeatedly swaps the largest value to the end and repairs the heap.
Time: O(n log n) in every case. Space: O(1). What Big-O notation means.
Last updated
About this lesson
- Concept it teaches
- Max-heap in the array, in-place O(n log n)
- Canonical source
- Cormen et al., Introduction to Algorithms, section 6.4
- Builds on
- Selection sort
- Concept it teaches
- Max-heap in the array, in-place O(n log n)
- Canonical source
- Cormen et al., Introduction to Algorithms, section 6.4
- Builds on
- Selection sort
I already know this: go to the check
See
+10 XP
Watch the real code run, one step at a time. Change the input and see what happens.
Predict first. Before you press Play, guess what the first comparison will be.
Run Heap sort
- Comparisons
- 0
- Writes
- 0
- Step
- 1/66
- Current
- Comparing
- Swapped
- Done
- Pivot
- In range
Array. index 0: 5; index 1: 3; index 2: 8; index 3: 1; index 4: 9; index 5: 2; index 6: 7.
Sort 7 numbers in two phases: arrange the array as a max-heap, then take the largest value out 6 times.
Sort 7 numbers in two phases: arrange the array as a max-heap, then take the largest value out 6 times.
Step 1/66comparisonwrite
With focus on the player: Space play · ← → step · Home End jump
Curious how it compares? Race heap sort against another sort.
Understand
+15 XP
The idea in plain words: why it works, what it costs, when to use it. One question at the end.
Heap sort is a comparison-based sorting algorithm that first arranges the array as a max-heap, then repeatedly swaps the largest value, the root, to the end and repairs the heap. It sorts in place and always runs in O(n log n) time.
A max-heap is stored in the array itself: the children of index i are at 2i + 1 and 2i + 2, and every value is at least as large as its children. So index 0 always holds the largest value.
How it works
- Build the heap. Indexes from
n / 2up are leaves, so they are already heaps. Go from the last parent back to index 0 and sift down each value: swap it with its larger child until it is at least as large as both. - Take the largest out. Swap the root with the last value of the heap. That index is now final, so the heap is one place shorter.
- Sift the new root down to repair the heap, and repeat step 2 until the heap has one value left.
Time and space complexity
A sift down walks at most the height of the heap, about log n levels. The second phase does it n - 1 times, so it costs O(n log n) however the values are ordered. Building the heap costs only O(n).
| Best case time | O(n log n) |
|---|---|
| Average case time | O(n log n) |
| Worst case time | O(n log n) |
| Extra space | O(1) |
- Best, average and worst:
O(n log n), because the second phase never depends on the order of the input. - Space:
O(1), because everything happens inside the array: it is in place.
A worked example
Sort 5, 3, 8, 1, 9, 2, 7. Phase 1 builds the max-heap: index 2 (the 8) already beats its children, index 1 swaps the 3 with its larger child 9, and index 0 swaps the 5 with the 9 and then stays at index 1, because its children 1 and 3 are smaller. Then phase 2 runs 6 rounds. Each round swaps the root into its final place and sifts the new root down inside the shorter heap. The table shows the heap and the finished part after each round.
| After | Heap, indexes 0 and up | Final values at the end |
|---|---|---|
| Phase 1, build | 9, 5, 8, 1, 3, 2, 7 | none |
| Round 1: 9 to index 6 | 8, 5, 7, 1, 3, 2 | 9 |
| Round 2: 8 to index 5 | 7, 5, 2, 1, 3 | 8, 9 |
| Round 3: 7 to index 4 | 5, 3, 2, 1 | 7, 8, 9 |
| Round 4: 5 to index 3 | 3, 1, 2 | 5, 7, 8, 9 |
| Round 5: 3 to index 2 | 2, 1 | 3, 5, 7, 8, 9 |
| Round 6: 2 to index 1 | 1 | 2, 3, 5, 7, 8, 9 |
The last value left in the heap, 1, is already in place, so the array reads 1, 2, 3, 5, 7, 8, 9. The whole run makes 19 comparisons and 24 writes, where a swap counts as two writes. Phase 1 used 8 of those comparisons and 2 swaps. The array was sorted without any extra array, since the heap and the finished part share the same 7 slots.
Pseudocode
The code counts indexes from 0, so the children of i are 2i + 1 and 2i + 2. SIFT-DOWN is the textbook's MAX-HEAPIFY, and the first loop is BUILD-MAX-HEAP. The parameter size is the length of the heap.
HEAP-SORT(A)
n = A.length
for i = floor(n / 2) - 1 downto 0
SIFT-DOWN(A, i, n)
for end = n - 1 downto 1
swap A[0] and A[end]
SIFT-DOWN(A, 0, end)
SIFT-DOWN(A, i, size)
while true
l = 2i + 1
r = 2i + 2
largest = i
if l < size and A[l] > A[largest]
largest = l
if r < size and A[r] > A[largest]
largest = r
if largest == i
return
swap A[i] and A[largest]
i = largest
The second loop passes end as the size, so the heap shrinks by one each round and never touches the values that are already final. That is the fix for the mistake in the box below.
Stability
Heap sort is not stable. Sorting [2a, 2b, 1] gives [1, 2b, 2a]: the two equal values changed places.
When to use it, and when not to
- Use it when you need a guaranteed
O(n log n)time and little extra memory. Merge sort has the guarantee but needsO(n)space; quick sort is in place but can degrade toO(n²). - Avoid it when you need a stable sort, or when speed on typical data matters most: quick sort is usually faster in practice.
Where it is used
- The fallback in introsort. Introsort starts as quick sort and switches to heap sort when the recursion goes deeper than a fixed limit, which caps the worst case at
O(n log n). It is the design behindstd::sortin GNU's libstdc++, among other C++ standard libraries. - Kernels with little stack. The Linux kernel's
sort()is a heap sort. Its source gives the reasons: it is non-recursive, so it needs no deep stack, and it avoids theO(n²)worst case of quick sort without extra code. - Partial sorting. To get only the
ksmallest or largest values, build the heap inO(n)and run the second phase forkrounds. That costsO(n + k log n), far less than a full sort whenkis small.
Variations and related ideas
Heap sort is selection sort with a heap to find the largest remaining value in O(log n) instead of scanning for it, which turns O(n²) into O(n log n). The heap itself is the subject of the binary heap lesson, which uses a min-heap. To compare it with other sorts on the same inputs, see merge sort vs heap sort (same time guarantee, but merge sort is stable and needs O(n) extra space), quick sort vs heap sort and selection sort vs heap sort. Smoothsort is a variant that runs faster on nearly sorted input.
One question to finish
In an array-based max-heap with indexes starting at 0, where are the children of index i?
Predict
+20 XP
The run stops and asks what happens next. The real run says if you were right.
Practice
+30 XP
Order the lines, fill in the gap, trace it by hand. The real run corrects every answer.
Run it by hand
Run heap sort yourself. Make each decision the algorithm makes; the real run checks every move.
Check yourself
Four questions from memory. They also join your daily review. Questions return on a spaced schedule: right answers come back later, misses come back tomorrow.