A heap is a complete binary tree with a simple ordering rule: in a min-heap, every parent is smaller than or equal to its children, so the smallest element is always at the root. (A max-heap flips the comparison.) The heap does not fully sort its elements; it only guarantees the extreme value sits on top, which is exactly what you need for a priority queue.
Why Heaps Matter#
Whenever a problem asks for the “top k”, the “kth largest”, the “next smallest”, or “process the cheapest item next”, a heap is usually the answer. Dijkstra’s shortest-path algorithm, Huffman coding, merge-k-sorted-lists, and median-of-a-stream all lean on heaps. The heap gives you repeated access to the min or max without paying O(n log n) to fully sort.
Key Operations and Their Big-O#
Because a heap is stored as an array and its height is O(log n), the core operations are cheap:
| Operation | Time | Notes |
|---|---|---|
| Peek min/max | O(1) | It is the root |
| Push (insert) | O(log n) | Bubble up |
| Pop (extract root) | O(log n) | Sift down |
| Build heap from n items | O(n) | Heapify, not n pushes |
| Search arbitrary value | O(n) | Heaps are not for lookup |
Note the last row: a heap answers “what is the extreme?” fast but “does value x exist?” slowly. Use a hash set for membership.
A Short Example#
Python’s heapq is a min-heap. For “k largest”, keep a heap of size k and evict the smallest:
1import heapq
2
3def k_largest(nums, k):
4 heap = nums[:k]
5 heapq.heapify(heap) # O(k)
6 for x in nums[k:]:
7 if x > heap[0]: # bigger than the smallest kept
8 heapq.heapreplace(heap, x)
9 return heap # the k largest, unordered
Common Pitfalls#
- Wanting a max-heap in Python.
heapqis min-only; push-value(or a wrapper) to simulate a max-heap. - Building with repeated pushes.
heapifyis O(n); n individual pushes is O(n log n). Prefer heapify when you have all the data up front. - Treating a heap like a sorted list. It is not sorted beyond the root. Popping everything gives you sorted order, but iterating the array does not.
- Comparing complex items. Pushing tuples works because Python compares element-wise, but a tie on the first element then compares the second, which can raise on non-comparable payloads. Add a tiebreaker index.
Where the Curriculum Covers This#
In the 60-day challenge:
- Day 17: Heaps
- Day 28: Heapsort
- Day 43: Dijkstra’s Algorithm (heaps in action)
Related Resources#
- Trees study guide: the tree structure a heap is built on.
- Sorting: heapsort and how it compares to quicksort and mergesort.
- Big-O cheat sheet: complexity tables at a glance.
- Interview prep hub: top-k and streaming questions in context.