Heap (Priority Queue)
A complete binary tree stored in an array that gives O(1) access to the smallest (or largest) element.
Worth knowing first
#How does it work?
A heap is a tree that always gives instant access to the smallest (min-heap) or largest (max-heap) element. Min-heap rule: every parent is smaller than or equal to its children, so the minimum sits at the root.
A heap is a complete binary tree: levels fill left to right without gaps. That lets it live in a plain array without pointers: the children of index i are at 2i + 1 and 2i + 2, and its parent at (i - 1) / 2.
Insert puts the new element at the end and moves it up while it is smaller than its parent (sift up). Extract-min moves the last element to the root and pushes it down while a child is smaller (sift down). A heap isn't sorted; it just answers "what's the smallest?" fast.
#Try it yourself
Min-heap: every parent is smaller than or equal to its children, so the smallest element is always at the root. The tree is actually stored in the array below.
#Basic operations
- insert(x)
- Appends x to the array, then swaps it with its parent while it is smaller.
- extractMin()
- Removes the root, puts the last element there, and swaps it down with its smaller child.
- peek()
- Reads the minimum at the root without removing it.
- heapify
- Turns an arbitrary array into a heap in O(n).
#Example code
The same algorithm in 8 languages. Every program is compiled, run and checked to print the same output.
class MinHeap:
"""Min-heap in a list: the children of i are 2i + 1 and 2i + 2, its parent is (i - 1) // 2."""
def __init__(self) -> None:
self.items: list[int] = []
def push(self, value: int) -> None:
a = self.items
a.append(value)
i = len(a) - 1
# Sift up: swap with the parent while smaller.
while i > 0 and a[(i - 1) // 2] > a[i]:
a[i], a[(i - 1) // 2] = a[(i - 1) // 2], a[i]
i = (i - 1) // 2
def pop(self) -> int:
a = self.items
if not a:
raise IndexError("heap is empty")
smallest_value = a[0]
last = a.pop()
if a:
a[0] = last # move the last element to the root
# Sift down: swap with the smaller child while a child is smaller.
i = 0
while True:
left, right, smallest = 2 * i + 1, 2 * i + 2, i
if left < len(a) and a[left] < a[smallest]:
smallest = left
if right < len(a) and a[right] < a[smallest]:
smallest = right
if smallest == i:
break
a[i], a[smallest] = a[smallest], a[i]
i = smallest
return smallest_value
def __len__(self) -> int:
return len(self.items)
heap = MinHeap()
for v in (5, 3, 8, 1, 9, 2):
heap.push(v)
# Popping repeatedly yields the values in ascending order.
print(*[heap.pop() for _ in range(len(heap))])#Complexity
| Operation | Time |
|---|---|
| peek (look at the minimum) | O(1) |
| insert | O(log n) |
| extractMin | O(log n) |
| heapify (build from array) | O(n) |
| Search for an arbitrary value | O(n) |
| Memory | O(n) |
Because a heap is always a complete tree, its height is log₂ n, and sift up and sift down take at most that many steps. A heap keeps no order between siblings, so searching for an arbitrary value is O(n). Extracting all n elements one by one gives heap sort, which runs in O(n log n).
#When to use it?
The standard implementation of priority queues: OS task scheduling, Dijkstra's and Prim's algorithms, event simulations, "top k" problems and running medians. Python's heapq and Java's PriorityQueue are heaps.
#Practice
Log in to answer questions and save your progress.
Easy
Where is the smallest element in a min-heap?
- 1At the root
- 2In the rightmost leaf
- 3At the end of the array
- 4Anywhere
What is the complexity of inserting into a heap?
- 1O(log n)
- 2O(1)
- 3O(n)
- 4O(n log n)
In an array-based heap, at which index is the left child of index i?
- 12i + 1
- 2i + 1
- 3i / 2
- 42i - 1
Medium
After inserting 1 into the min-heap [2, 5, 3, 9, 6], what does the array look like?
- 1[1, 5, 2, 9, 6, 3]
- 2[1, 2, 3, 5, 6, 9]
- 3[2, 5, 3, 9, 6, 1]
- 4[1, 2, 5, 3, 9, 6]
Hard
What is a heap used for in Dijkstra's shortest path algorithm?
- 1To quickly pick the closest unprocessed node
- 2To sort the edges
- 3To store visited nodes
- 4To detect cycles
#Up next
Lessons that build on this one: