DSA Notes
Master core heap operations — insert with bubble-up, delete with bubble-down, heapify individual nodes, and build a heap in O(n) time from an unordered array.
Overview of Heap Operations
| Operation | Time Complexity | Description |
|---|---|---|
| Insert | O(log n) | Add element, bubble up to restore heap property |
| Extract max/min | O(log n) | Remove root, replace with last, bubble down |
| Peek | O(1) | Return root element without removing |
| Build heap | O(n) | Convert unordered array into a heap |
| Heapify (sift down) | O(log n) | Fix heap property for a single subtree |
Insert (Bubble Up / Sift Up)
To insert a new element into a max-heap:
- Place the new element at the end of the array (next available position in the complete tree).
- Bubble up: Compare with parent. If larger than parent, swap. Repeat until the element is smaller than its parent or reaches the root.
Dry Run: Insert 60 into Max-Heap
| Initial heap | [50, 30, 40, 20, 25, 35] |
| Step 1 | Append 60 at the end |
| Step 2 | Compare with parent (index (6-1)//2 = 2, value 40) |
| 60 > 40 | swap |
| Step 3 | Compare with parent (index (2-1)//2 = 0, value 50) |
| 60 > 50 | swap |
Python Implementation
Extract Max / Delete Root (Bubble Down / Sift Down)
To remove the root (maximum element) from a max-heap:
- Replace the root with the last element in the array.
- Remove the last position (shrink array by 1).
- Bubble down: Compare the new root with its children. Swap with the larger child if it is greater. Repeat until heap property is restored.
Dry Run: Extract Max from [60, 30, 50, 20, 25, 35, 40]
| Step 1 | Save max (60). Replace root with last element (40). Remove last. |
| Step 2 | Compare 40 with children: left=30, right=50. Larger child = 50 (right). |
| 40 < 50 | swap with right child. |
| Step 3 | Compare 40 with children: left=35. (right child index 6 is out of bounds) |
| 40 > 35 | no swap needed. DONE. |
| Result | Extracted 60. New heap: [50, 30, 40, 20, 25, 35] |
| Tree | 50 |
Python Implementation
Build Heap: O(n) from Unordered Array
Given an unordered array, we can convert it into a heap. The naive approach (insert elements one by one) takes O(n log n). But there is a smarter way: bottom-up heapify in O(n).
The Key Insight
Leaves are already valid heaps (single-element heaps). Start from the last internal node and apply bubble-down (heapify) moving upward. Each node is "sifted down" at most to the bottom of its subtree.
Algorithm
- Identify the last internal node: index
(n//2) - 1 - For each node from this index down to 0, call bubble_down.
Dry Run: Build Heap from [4, 10, 3, 5, 1]
| Array | [4, 10, 3, 5, 1] |
| Last internal node | (5//2)-1 = 1 |
| Step 1 | Heapify index 1 (value 10) |
| Children | 5, 1. Largest = 10. No swap needed. |
| Step 2 | Heapify index 0 (value 4) |
| Children | 10, 3. Largest = 10 (left child). |
| Swap 4 and 10 | [10, 4, 3, 5, 1] |
| Children | 5, 1. Largest = 5 (left child). |
| Swap 4 and 5 | [10, 5, 3, 4, 1] |
| Final heap | [10, 5, 3, 4, 1] ✓ (max-heap property satisfied) |
| Tree | 10 |
Python Implementation
Why Build Heap is O(n), Not O(n log n)
Intuitively, most nodes are near the bottom and barely move. Formally:
- Nodes at height h: at most ⌈n / 2^(h+1)⌉
- Each node at height h does at most h swaps in bubble_down
Total work = Σ (h=0 to log n) of [⌈n/2^(h+1)⌉ × h] = n × Σ (h=0 to ∞) [h / 2^(h+1)] = n × 1 (the series converges to a constant) = O(n)
Half the nodes are leaves (height 0, zero work). A quarter are at height 1 (one swap max). Only one node (root) might travel the full log n distance.
C++ Implementation
Decrease/Increase Key
To change a key's value:
- Increase key (max-heap): Update value, then bubble up (it might now be larger than parent).
- Decrease key (max-heap): Update value, then bubble down (it might now be smaller than children).
Operation Summary
| INSERT: Place at end | Bubble UP |
| EXTRACT MAX/MIN: Swap root with last | Remove last → Bubble DOWN |
| BUILD HEAP: For each internal node (bottom-up) | Bubble DOWN |
| INCREASE KEY: Update value | Bubble UP |
| DECREASE KEY: Update value | Bubble DOWN |
The two fundamental primitives are bubble-up and bubble-down. Every operation reduces to one of them.
Key Takeaways
Heap operations revolve around two movements: bubble up (for inserts and key increases) and bubble down (for extractions and key decreases). The build-heap operation achieves O(n) by exploiting the fact that most nodes have small heights. Understanding these operations deeply is essential for implementing priority queues, heap sort, and graph algorithms like Dijkstra's.
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for Heap Operations.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this Data Structures & Algorithms topic.
Search Terms
data-structures-algorithms, data structures & algorithms, data, structures, algorithms, heaps, heap, operations
Related Data Structures & Algorithms Topics