Comparisons

Quick Sort vs Heap Sort vs Merge Sort

Quick Sort, Heap Sort and Merge Sort are all O(n log n) on average, but they trade speed, memory and stability differently. A practical comparison of all three.

Aman Jaiman
9 min read
On this page +
  1. In plain English
  2. The core trade-off
  3. When to choose each
  4. The best of both: Introsort
  5. Merge Sort vs Heap Sort
  6. When to choose each
  7. Frequently asked questions

Quick Sort vs Heap Sort pits average-case speed against worst-case reliability. Both are in-place comparison sorts, but they behave very differently under pressure. Understanding the trade-off explains why production libraries combine them in Introsort.

The core trade-off #

Quick Sort is faster on average (O(n log n)) thanks to cache-friendly partitioning, but its worst case is O(n²). Heap Sort is slower on average due to scattered memory access, but guarantees O(n log n) on every input. Both use roughly O(1)-O(log n) extra space and neither is stable.

When to choose each #

Choose Quick Sort for general-purpose speed where average performance matters most. Choose Heap Sort when you need a hard worst-case guarantee — real-time systems, security-sensitive code, or anywhere an adversary might craft inputs to trigger Quick Sort's O(n²) blow-up.

The best of both: Introsort #

You do not always have to choose. Introsort runs Quick Sort but falls back to Heap Sort when recursion gets too deep, capturing Quick Sort's speed and Heap Sort's guarantee. This hybrid is what C++ std::sort uses.

Merge Sort vs Heap Sort #

Quick Sort aside, the other two members of the O(n log n) family make an interesting pair, because they agree on their time guarantee and disagree on almost everything else.

Merge SortHeap Sort
Worst caseO(n log n)O(n log n)
Best caseO(n log n)O(n log n)
Auxiliary spaceO(n)O(1)
StableYesNo
Cache behaviourGood (sequential streams)Poor (jumps across the array)
Adaptive to sorted inputSomewhat (Tim Sort variants)No

The exchange is stark: Heap Sort gives you the same worst-case guarantee as Merge Sort for no extra memory at all, and charges you stability plus cache performance for it.

Heap Sort's cache problem is worth understanding, because it explains why an algorithm with such attractive theoretical properties is rarely the default. Sifting a value down a binary heap jumps from index i to 2i+1, then to 4i+3, and so on. Those addresses are far apart, so each step tends to miss the cache. Merge Sort walks two runs sequentially, which is exactly the pattern CPUs prefetch well. In wall-clock terms Merge Sort usually beats Heap Sort despite doing more memory traffic on paper.

When to choose each #

Choose Quick Sort when you are sorting primitives, want the best average-case speed, and can accept instability. Use a randomised or median-of-three pivot. This is the right default for numeric arrays.

Choose Merge Sort when stability matters — sorting records by one field after another — or when you need a hard O(n log n) guarantee and can afford O(n) extra memory. It is also the natural choice for linked lists, where it needs no extra space at all, and for data too large to fit in memory.

Choose Heap Sort when memory is genuinely tight and you still cannot tolerate a quadratic worst case. Embedded systems and kernel code pick it for exactly this reason. It is also the safety net inside introsort: C++'s std::sort runs Quick Sort but switches to Heap Sort if recursion gets too deep, which is how it advertises O(n log n) worst case while keeping Quick Sort's speed.

Run all three on the same shuffled array in the visualiser and watch the swap counters rather than the clock. Heap Sort's restructuring, Merge Sort's steady merging and Quick Sort's partitioning produce three completely different signatures of work.

Found this useful?

Share it with someone who is learning this too.

Questions

Frequently asked questions

Is Heap Sort better than Quick Sort? +
Heap Sort has a better worst case (always O(n log n)) and uses O(1) space, but Quick Sort is typically 2-3x faster on average due to cache locality. Most code uses Introsort to get both benefits.
Why is Quick Sort faster than Heap Sort? +
Quick Sort accesses memory sequentially during partitioning, which is cache-friendly. Heap Sort jumps between parent and child indices, causing more cache misses.
Which uses less memory, Merge Sort or Heap Sort? +
Heap Sort, by a wide margin. It sorts entirely within the original array using O(1) auxiliary space, while Merge Sort needs an O(n) buffer to merge into — roughly doubling peak memory for the duration of the sort. If memory is the binding constraint, Heap Sort wins outright.
Which is stable, Merge Sort or Heap Sort? +
Merge Sort is stable; Heap Sort is not. Merge Sort preserves the original relative order of equal elements because the merge step breaks ties in favour of the left run. Heap Sort destroys that order as soon as it builds the heap, since sifting moves values across the array with no regard for where they started. If you need to sort by one field and keep an earlier ordering intact, Heap Sort cannot do it.

See it in motion

Watch this algorithm and nine others run step by step, with live pseudocode and comparison counters.

Launch the visualiser
Aman Jaiman
Written by
Aman Jaiman

Software engineer at a stealth-stage startup, and previously a front-end engineer for around a year and a half.

Keep reading

Related guides

Link copied