Introduction
Heapsort sorts an array by first arranging it into a max-heap and then repeatedly moving the maximum to the end. It is the only standard comparison sort that is both in place ( auxiliary space) and guaranteed in the worst case. Its weaknesses are that it is not stable, not adaptive, and usually slower in practice than quicksort because its memory accesses jump around the array.
The heap itself (shape and heap properties, the array layout, MAX-HEAPIFY, BUILD-MAX-HEAP and why building is ) is covered in Binary Heaps. This note uses those results and concentrates on heapsort as a sorting algorithm: its trace, its exact cost, its properties, and the selection problems it solves.
Prerequisites
- Binary Heaps: 1-based array layout (children of at and ), MAX-HEAPIFY in , BUILD-MAX-HEAP in .
- Elementary Sorting: stability, in-place and adaptive sorting.
The algorithm
Purpose. Sort into non-decreasing order in place. Input. . Output. The same array, sorted.
Pseudocode uses 1-based arrays, <- for assignment and A[i..j] for the subarray from position to position .
HEAPSORT(A, n)
BUILD-MAX-HEAP(A, n) // Theta(n); see Binary Heaps
for i <- n downto 2
exchange A[1] with A[i] // current maximum to its final place
A.size <- A.size - 1 // A[i..n] is now outside the heap
MAX-HEAPIFY(A, 1) // restore the heap on A[1..i-1]Loop invariant. At the start of the iteration for index :
- is a max-heap containing the smallest elements of the input.
- contains the largest elements, in sorted order.
The exchange puts the largest of the heap elements at position , which extends part 2; MAX-HEAPIFY restores part 1 on the smaller heap (its precondition holds because only the root changed). When the loop ends at , the single remaining element is the minimum, so the whole array is sorted.
Descending order. Use a min-heap instead (MIN-HEAPIFY, BUILD-MIN-HEAP); the minimum moves to the end each time, so the array ends in non-increasing order.
Worked example
Input , . The Binary Heaps note traces BUILD-MAX-HEAP on this input; it produces the heap after 5 exchanges.
The sorting phase then runs . In the table, the part after the bar is outside the heap and already in final position.
| Root moved to | Array after exchange and MAX-HEAPIFY | Sift-down exchanges | |
|---|---|---|---|
| 9 | 25 | 20 13 17 8 7 4 2 5 | 25 | 2 |
| 8 | 20 | 17 13 5 8 7 4 2 | 20 25 | 1 |
| 7 | 17 | 13 8 5 2 7 4 | 17 20 25 | 2 |
| 6 | 13 | 8 7 5 2 4 | 13 17 20 25 | 2 |
| 5 | 8 | 7 4 5 2 | 8 13 17 20 25 | 1 |
| 4 | 7 | 5 4 2 | 7 8 13 17 20 25 | 1 |
| 3 | 5 | 4 2 | 5 7 8 13 17 20 25 | 1 |
| 2 | 4 | 2 | 4 5 7 8 13 17 20 25 | 0 |
Result: . The sorting phase made 10 sift-down exchanges and 22 key comparisons (MAX-HEAPIFY compares with each existing child, up to two comparisons per level).
Look at the first row in detail. After exchanging 25 with , the heap has 4 at the root. Its children are 13 and 20, so 4 is exchanged with 20 (index 3). The children of index 3 are now 17 (index 6) and 2 (index 7), so 4 is exchanged with 17. Index 6 has no children inside the heap of size 8, so the sift-down stops.

Analysis
Time
- BUILD-MAX-HEAP: (proof in Binary Heaps).
- The loop runs times; each MAX-HEAPIFY on a heap of elements costs . Total .
So heapsort is in the worst case. For inputs with distinct keys it is also (the matching best-case bound for distinct keys is a known but harder result), so its time is on every input of distinct keys, including already sorted input. It is not adaptive.
| Case | Time | Remark |
|---|---|---|
| Worst | at most about key comparisons with the two-comparison MAX-HEAPIFY | |
| Average | ||
| Best, distinct keys | sorted or reverse-sorted input does not help | |
| Best, all keys equal | every MAX-HEAPIFY stops at once (no child is strictly larger) |
A reverse-sorted array () is already a max-heap, so BUILD-MAX-HEAP makes no exchanges, but the sorting phase still costs .
Space
MAX-HEAPIFY written as a loop (instead of tail recursion) needs extra space, and the heap occupies the input array. Heapsort is therefore in place with auxiliary space. With the recursive MAX-HEAPIFY as written in CLRS, the stack can reach frames; this is a property of that implementation, not of the algorithm.
Stability
Heapsort is not stable. The smallest example has two equal keys: for , the array is already a max-heap ( is not larger than ), and the first exchange of with produces . The long-distance exchanges between the root and the end of the heap reorder equal keys in general. Binary Heaps gives a three-element example.
Properties
| Property | Heapsort |
|---|---|
| Worst-case time | |
| Auxiliary space | (iterative sift-down) |
| In place | yes |
| Stable | no |
| Adaptive | no |
| Comparison-based | yes, asymptotically optimal |
| Online | no (needs all elements before the first output in sorted order) |
Compared with quicksort and merge sort.
- Against quicksort: heapsort's worst case is instead of , but its average constant is larger and its access pattern (jumping between and ) is unfriendly to caches. Introsort uses quicksort and falls back to heapsort when the recursion becomes too deep.
- Against merge sort: heapsort needs no buffer, but merge sort is stable and works well on linked lists and external data.
Fewer comparisons. The "bottom-up" variant of heapsort first sifts the hole down to a leaf along the path of larger children (one comparison per level), then moves the displaced key back up. This cuts the comparisons of the sorting phase to about on average.
Where elements can sit in a max-heap
Consider where the minimum, or the -th largest, can be in a max-heap of distinct keys (1-based).
- Minimum. It has no larger descendant to be above, so it has no children: it is a leaf, in one of the positions . Finding it takes comparisons, a scan of the leaves; the heap order does not help beyond halving the search.
- Second largest. For , compare the children at positions 2 and 3. For , choose position 2 without a comparison; for , the statistic is undefined.
- -th largest. Every ancestor of a key is larger than it, so the -th largest has at most ancestors and lies at depth at most , in positions 1 to . For it is never at the root.
In the example heap : the leaves are positions 5 to 9 (keys 7, 17, 2, 5, 4) and the minimum 2 is at position 7; the second largest, 20, is at position 3; the third largest, 17, is at position 6, depth 2 (). Note that the leaves hold 17, the third largest, so "the leaves hold the smallest keys" is false.
Selection with heaps
Related material. Heap-based selection is not a separate item of the GATE syllabus. It is included because it is commonly studied together with heaps and heapsort.
Heaps also solve "find the largest" without sorting everything.
| Problem | Method | Time | Extra space |
|---|---|---|---|
| largest of (array given) | build a max-heap, extract times | in place | |
| largest of a stream | keep a min-heap of the largest seen; replace its root when a larger element arrives | ||
| -th smallest | min-heap and extract-mins, or a max-heap of size | or | |
| Partial sort of the top | stop after extraction rounds; if , the final remaining root is already in place; the last positions hold them in order |
The selection bounds above assume . For , the streaming method takes ; selecting zero elements needs no heap.
For a single order statistic, quickselect is expected with distinct keys for the displayed Lomuto version, or with equality-aware partitioning for duplicates; heaps win when is small or the data arrives as a stream.
Edge cases
- : BUILD-MAX-HEAP does nothing and the loop does not run.
- : one exchange in the loop, possibly after one exchange in the build.
- Equal keys: the algorithm is correct; stability is lost.
- 0-based arrays: children at and , parent at ; the loop runs down to 1.
Important properties and observations
- After iterations of the sorting loop, the last positions hold the largest elements in sorted order, and is the largest of the rest.
- The sorting phase dominates: to build, to sort (for distinct keys).
- The total number of exchanges is at most the build exchanges plus root exchanges plus sift-down exchanges.
- "Heapsort on sorted input with distinct keys is " is false; "heapsort is stable" is false; "heapsort needs extra space" is false.
GATE examination perspective
- Intermediate arrays. the array after BUILD-MAX-HEAP, or after the first iterations of the sorting loop. Trace each sift-down level by level and keep track of the shrinking heap size.
- Counting. the number of exchanges or comparisons for a small input; state whether build-phase operations are included.
- Properties. in place, not stable, worst case, not adaptive.
- Selection. largest in with a max-heap; streaming top with a min-heap of size .
- Positions. in a max-heap the minimum is a leaf (positions to ); the -th largest is at depth at most .
Summary
Sources
- T. H. Cormen, C. E. Leiserson, R. L. Rivest, C. Stein, Introduction to Algorithms, 3rd ed., MIT Press, 2009: Chapter 6, Section 6.4 (the heapsort algorithm and its O(n lg n) bound), Exercise 6.4-5 (best case for distinct keys), Section 6.5 (priority queues).