C++ STL
Heap Operations
Complete lesson for Heap Operations using LEARNCODEGURU’s 6-level learning model — from basics to advanced practice, with C++ OOP and STL where relevant.
Basics — Heap Operations
Section: C++ STL. C++ heap algorithms — make_heap, push_heap, pop_heap, sort_heap with real-life examples.
What is a heap (STL)?
- In the STL, a **heap** is a **priority arrangement** of a random-access range (usually a
vector). - Default is a **max-heap**: the **largest** element sits at
front()(v[0]). - Algorithms live in
:make_heap,push_heap,pop_heap,sort_heap,is_heap. - Not the same as “heap memory” (
new/delete) — that is a different meaning of the word. - **Real-life:** a triage board where the most urgent patient is always at the top of the list.
| Idea | Meaning |
|---|---|
| Max-heap | Parent ≥ children; largest at index 0 |
| Min-heap | Use greater<> comparator; smallest at front |
| Not fully sorted | Only the top is guaranteed extreme |
| Range-based | Works on [first, last) in a vector/array |
| vs priority_queue | Heap algos = DIY; PQ = packaged adapter |
Why use heap algorithms?
- Process “most important next” without fully sorting every time.
- Build or adjust a priority structure in-place on a vector.
- Understand what
priority_queuedoes under the hood.
| Benefit | What you gain |
|---|---|
| Best-first access | Top element always ready at v.front() |
| Incremental updates | push_heap / pop_heap after changes |
| In-place | No separate tree container required |
| Flexible | Custom comparators for min-heap / custom priority |
| Learning | Clarifies heapsort and priority queues |
Heap vs priority_queue vs sort
- Same priority idea — different APIs and when you use them.
| Feature | Heap algorithms | priority_queue | sort |
|---|---|---|---|
| Interface | On a vector range | Adapter (push/top/pop) | Fully orders range |
| See all elements? | Yes (vector visible) | Only top | Yes, sorted |
| After build | Partial order (heap) | Heap inside | Total order |
| Typical use | Custom / in-place heap | Everyday priority jobs | Need full sort |
| Real-life | DIY triage board | Ready-made ticket triage | Print full ranking |
| Header | | | |
make_heap — build a heap
make_heap(first, last)rearranges[first, last)into a max-heap.- Afterward,
*first(orv.front()) is the largest. - **Real-life:** take today’s emergency tickets and arrange so the hottest issue is on top.
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> v = {3, 1, 4, 2};
make_heap(v.begin(), v.end());
cout << v.front() << "\n"; // 4
return 0;
} push_heap — add then sift up
- 1)
v.push_back(x)— new item at the end. - 2)
push_heap(v.begin(), v.end())— restore the heap property. - **Real-life:** a new patient arrives; add to the board, then bubble to the right urgency slot.
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> v = {3, 1, 4, 2};
make_heap(v.begin(), v.end());
v.push_back(9);
push_heap(v.begin(), v.end());
cout << v.front() << "\n"; // 9
return 0;
} pop_heap — remove the top
pop_heapswaps the top to the **end** and re-heaps the rest.- Then
v.pop_back()actually removes that former top. - **Real-life:** serve the most urgent ticket; move it aside, then reorganize who is next.
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> v = {3, 1, 4, 2};
make_heap(v.begin(), v.end());
pop_heap(v.begin(), v.end());
int top = v.back();
v.pop_back();
cout << top << "\n"; // 4
cout << v.front() << "\n"; // next largest among remaining
return 0;
} sort_heap and is_heap
sort_heapturns a **valid heap** into a **sorted** ascending range (destroys heap order).is_heapchecks whether a range is already a heap.- **Real-life:** after triage is done,
sort_heapis like printing a final ranked list from the board.
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> v = {3, 1, 4, 2};
make_heap(v.begin(), v.end());
cout << boolalpha << is_heap(v.begin(), v.end()) << "\n"; // true
sort_heap(v.begin(), v.end());
for (int x : v) cout << x << " ";
cout << "\n"; // 1 2 3 4
return 0;
} Min-heap with a comparator
- Pass
greater(or a lambda) as the third argument to heap algorithms.{} - Then
front()is the **smallest**. - **Real-life:** next-event simulation — earliest timestamp should be on top.
#include <algorithm>
#include <functional>
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> v = {3, 1, 4, 2};
make_heap(v.begin(), v.end(), greater<int>{});
cout << v.front() << "\n"; // 1
return 0;
} Real-life examples
- Heaps model “always handle the extreme next”.
| Real-life situation | Heap role | STL angle |
|---|---|---|
| Hospital triage | Most critical patient first | Max-heap by urgency |
| IT helpdesk tickets | Highest priority ticket on top | make_heap on priority scores |
| CPU job scheduling | Ready queue by priority | push_heap / pop_heap |
| Top-K sales / scores | Keep best K | Min-heap of size K or max-heap pops |
| Event simulation | Next event by time | Min-heap of timestamps |
| Huffman coding | Merge two smallest repeatedly | Min-heap of frequencies |
| Dijkstra / best-first | Closest / best node next | Often via priority_queue |
| Live leaderboard peek | Show current #1 fast | v.front() after heapify |
| Print queue by urgency | Urgent jobs before normal | Max-heap of job priority |
| Sensor alert board | Worst reading first | Max-heap of severity |
Heap applications
- Use heap ops when you repeatedly need the current max/min from a changing set.
| Application | How the heap helps |
|---|---|
| Priority scheduling | Always pop the highest priority job |
| Top-K selection | Maintain a bounded heap of candidates |
| Heapsort | make_heap + repeated pop_heap / sort_heap |
| Median maintenance (pair of heaps) | Max-heap + min-heap balance |
| Graph best-first search | Expand best node next |
| Merge K sorted lists (idea) | Track next heads by value |
| Load balancing peek | Server with least load on a min-heap |
| Streaming extremes | Track max/min under inserts |
Application — helpdesk triage
- **Real-life:** ticket priorities on a board; always serve the highest first.
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> pri = {2, 5, 1, 4}; // higher = more urgent
make_heap(pri.begin(), pri.end());
while (!pri.empty()) {
pop_heap(pri.begin(), pri.end());
cout << "Serve priority " << pri.back() << "\n";
pri.pop_back();
}
return 0;
} Application — top-K with heap
- **Real-life:** show the top 3 scores from a contest without fully sorting for a report peek.
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> scores = {50, 90, 70, 95, 80};
make_heap(scores.begin(), scores.end());
for (int i = 0; i < 3 && !scores.empty(); ++i) {
pop_heap(scores.begin(), scores.end());
cout << scores.back() << " ";
scores.pop_back();
}
cout << "\n"; // 95 90 80
return 0;
} Key points to remember
- STL heap ≠ heap memory — it is a priority layout on a range.
- Default max-heap: largest at
front(); usegreater<>for min-heap. push_heaponly afterpush_back;pop_heapthenpop_back.sort_heapneeds a valid heap and produces ascending sorted order.- For most apps prefer
priority_queue; use heap algos for in-place/custom control. - Real-life: triage, scheduling, top-K, next-event, Huffman.
Advanced — Heap Operations
Typical workflow on a vector
make_heaponce (or start empty and onlypush_heap).- Insert:
push_back→push_heap. - Remove top:
pop_heap→ readback()→pop_back. - Optional finish:
sort_heapfor a full ascending list.
Application — next-event (min-heap)
- **Real-life:** simulation clock — always process the earliest event time.
#include <algorithm>
#include <functional>
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> times = {12, 3, 7, 1}; // event times
make_heap(times.begin(), times.end(), greater<int>{});
while (!times.empty()) {
pop_heap(times.begin(), times.end(), greater<int>{});
cout << "Event at t=" << times.back() << "\n";
times.pop_back();
}
return 0;
} Complexity notes
make_heap: O(n).push_heap/pop_heap: O(log n).sort_heap: O(n log n).is_heap: O(n).
Heap vs priority_queue — when which
- Everyday priority jobs → **
priority_queue** (clearer API). - Need the underlying vector visible / custom in-place logic → **heap algorithms**.
- Need a full sorted copy → **
sort** (orsort_heapafter heapify). - **Real-life:** product code usually wraps a PQ; interview/learning often asks for
make_heap.
Design tips
- Keep one consistent comparator on every heap call for that vector.
- Never assume the vector is fully sorted after
make_heap. - Do not call
push_heapunless the new element is already atend-1. - Document priority meaning (urgency, time, score).
- Prefer
priority_queuein application code unless you need the raw range.
Tricky Interview Points
Q1) What does make_heap do?
Answer Rearranges a random-access range into a heap (default max-heap with largest at front).
Q2) Is a heap fully sorted?
Answer No — only the heap property holds; only the top is guaranteed extreme.
Q3) Steps to remove the top with heap algorithms?
Answer pop_heap, then read back(), then pop_back.
Q4) Steps to insert into a heap on a vector?
Answer push_back the value, then push_heap on the full range.
Q5) Heap algorithms vs priority_queue?
Answer Heap algos operate on a visible range; priority_queue is an adapter exposing only top/push/pop.
Q6) How do you make a min-heap?
Answer Pass greater<T>{} (or a custom comparator) to make_heap / push_heap / pop_heap.
Q7) What does sort_heap do?
Answer Converts a valid heap into a sorted ascending range; the range is no longer a heap.
Q8) Give real-life examples of heaps.
Answer Hospital triage, helpdesk priority, CPU scheduling, top-K scores, next-event simulation, Huffman coding.
Q9) STL heap vs heap memory?
Answer Different meanings — STL heap is a priority structure; heap memory is dynamic allocation.
Q10) Complexity of push_heap?
Answer O(log n).
Q11) When prefer sort over a heap?
Answer When you need the entire sequence in order, not just repeated access to the extreme.
Q12) Where is the max in a default heap vector?
Answer At index 0 / front().
Simple Programs
make_heap basics
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> v = {3, 1, 4, 2};
make_heap(v.begin(), v.end());
cout << v.front() << "\n";
return 0;
} push_heap and pop_heap
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> v = {3, 1, 4};
make_heap(v.begin(), v.end());
v.push_back(10);
push_heap(v.begin(), v.end());
pop_heap(v.begin(), v.end());
cout << v.back() << "\n"; // 10
v.pop_back();
cout << v.front() << "\n";
return 0;
} sort_heap demo
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> v = {5, 1, 4, 2};
make_heap(v.begin(), v.end());
sort_heap(v.begin(), v.end());
for (int x : v) cout << x << " ";
cout << "\n";
return 0;
} Real-life — triage board
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> urgency = {1, 8, 3, 6};
make_heap(urgency.begin(), urgency.end());
cout << "Next patient urgency: " << urgency.front() << "\n";
return 0;
} Real-life — top-3 scores
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> s = {40, 99, 70, 85, 60};
make_heap(s.begin(), s.end());
for (int i = 0; i < 3; ++i) {
pop_heap(s.begin(), s.end());
cout << s.back() << " ";
s.pop_back();
}
cout << "\n";
return 0;
} Real-life — earliest event (min-heap)
#include <algorithm>
#include <functional>
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> t = {9, 2, 5};
make_heap(t.begin(), t.end(), greater<int>{});
cout << "Next event at " << t.front() << "\n"; // 2
return 0;
} Problem Solving Tricks
- STL heap = priority layout on a vector — not heap memory.
- Default max-heap: largest at front().
- push_back then push_heap; pop_heap then pop_back.
- sort_heap needs a valid heap → ascending sorted range.
- greater<> for min-heap (earliest / smallest first).
- priority_queue is usually easier for apps.
- Real-life: triage, scheduling, top-K, next-event, Huffman.
- is_heap to validate before sort_heap.
- Keep the same comparator on every call.
- After make_heap, do not assume full sorted order.
- Heapsort idea = make_heap + sort_heap.
- Document what the priority number means.
Practice Programs List
- Build a max-heap from {7, 2, 9, 4} and print front().
- push_back 11 and push_heap; confirm new front.
- pop_heap three times and print removed tops.
- Use sort_heap and print the ascending result.
- Build a min-heap of event times; print earliest.
- Simulate a helpdesk: serve tickets by priority until empty.
- Extract top-K contest scores with heap ops.
- Write a table: heap algos vs priority_queue vs sort.
- List 8 real-life heap uses in one comment block.
- Explain why pop_heap alone does not shrink the vector.
- Check is_heap before and after make_heap.
- Compare Dijkstra-style “best next” with a heap vs a full sort each time.