Stack, Queue and Priority Queue in C++ STL
In this lesson: Use stack, queue and priority_queue in C++ STL — push, pop, top, front — with examples and output. In Hindi & English.
Container adapters
stack, queue and priority_queue are container adapters: they sit on top of another container (usually deque or vector) and allow only a restricted set of operations. The restriction is the point — it makes your intent clear and prevents misuse.
| Adapter | Rule | Header | Add | Remove | Look at |
|---|---|---|---|---|---|
stack | LIFO — last in, first out | <stack> | push(x) | pop() | top() |
queue | FIFO — first in, first out | <queue> | push(x) at back | pop() from front | front(), back() |
priority_queue | Highest priority first | <queue> | push(x) | pop() | top() |
All three also have size() and empty(). None of them can be iterated with a range-based for.
std::stack — LIFO
Think of a pile of plates: you add and remove from the top only.
#include <iostream>
#include <stack>
int main() {
std::stack<int> s;
s.push(10);
s.push(20);
s.push(30);
std::cout << "top: " << s.top() << ", size: " << s.size() << "\n";
while (!s.empty()) {
std::cout << s.top() << " "; // read first
s.pop(); // then remove
}
std::cout << "\n";
return 0;
}Practical use: balanced brackets
#include <iostream>
#include <stack>
#include <string>
bool balanced(const std::string& expr) {
std::stack<char> st;
for (char c : expr) {
if (c == '(' || c == '[' || c == '{') {
st.push(c);
} else if (c == ')' || c == ']' || c == '}') {
if (st.empty()) return false;
char open = st.top();
st.pop();
if ((c == ')' && open != '(') ||
(c == ']' && open != '[') ||
(c == '}' && open != '{')) return false;
}
}
return st.empty();
}
int main() {
std::cout << balanced("{a[b(c)d]e}") << " "
<< balanced("(a[b)c]") << " "
<< balanced("((a)") << "\n";
return 0;
}Other stack uses: undo/redo, back button in a browser, function calls (the call stack), evaluating postfix expressions, depth-first search.
std::queue — FIFO
Think of a line at the fee counter: the first person to join is the first served.
#include <iostream>
#include <queue>
#include <string>
int main() {
std::queue<std::string> counter;
counter.push("Aman");
counter.push("Priya");
counter.push("Ravi");
std::cout << "first: " << counter.front()
<< ", last: " << counter.back() << "\n";
while (!counter.empty()) {
std::cout << "Serving " << counter.front() << "\n";
counter.pop();
}
return 0;
}Other queue uses: print queues, task scheduling, breadth-first search (BFS), buffering data between a producer and a consumer.
std::priority_queue — highest first
A priority_queue always gives you the largest element (a max-heap). push and pop are O(log n); top is O(1).
#include <iostream>
#include <queue>
#include <vector>
#include <functional>
int main() {
std::priority_queue<int> maxPq; // largest on top
std::priority_queue<int, std::vector<int>,
std::greater<int>> minPq; // smallest on top
for (int m : {66, 91, 78, 55, 84}) {
maxPq.push(m);
minPq.push(m);
}
std::cout << "Top 3 marks: ";
for (int i = 0; i < 3; i++) { std::cout << maxPq.top() << " "; maxPq.pop(); }
std::cout << "\nLowest mark: " << minPq.top() << "\n";
return 0;
}Priority queue of pairs or objects
Pairs compare by first, then second, so priority_queue<std::pair<int, std::string>> orders by marks. For your own class, give a comparison:
struct Patient { std::string name; int severity; };
auto cmp = [](const Patient& a, const Patient& b) { return a.severity < b.severity; };
std::priority_queue<Patient, std::vector<Patient>, decltype(cmp)> er(cmp);Uses: hospital emergency queues, Dijkstra's shortest path, picking top-K items, CPU scheduling.
stack vs queue vs priority_queue
| Point | stack | queue | priority_queue |
|---|---|---|---|
| Order out | Newest first | Oldest first | Highest priority first |
| Read next | top() | front() | top() |
| Default container | deque | deque | vector (as a heap) |
| push / pop cost | O(1) | O(1) | O(log n) |
| Real-life picture | Pile of plates | Queue at a counter | Hospital emergency ward |
Common mistakes
- Writing
int x = s.pop();—pop()returns nothing. Readtop()/front()first. - Calling
top(),front()orpop()on an empty adapter — undefined behaviour. Checkempty(). - Expecting
priority_queueto be sorted when printed — onlytop()is guaranteed to be the largest. - Forgetting
std::greater<int>needs<functional>(usually included via<queue>, but include it to be safe). - Trying
for (int x : myStack)— adapters have no iterators.
(1) Reverse a string using a stack<char>. (2) Simulate a printer with a queue<string> of document names. (3) Read 10 marks and print the three lowest using a min-heap priority_queue.
Summary
stack= LIFO withpush/pop/top;queue= FIFO withpush/pop/front/back.priority_queuereturns the largest element by default; usestd::greaterfor a min-heap.pop()returnsvoid— read the element first.- Always check
empty()beforetop(),front()orpop(). - They are adapters over
deque/vectorand cannot be iterated.
Related: STL introduction, list and deque, C: stack using array, C: queue.
Frequently Asked Questions
What is the difference between stack and queue in C++?
stack is LIFO (last in, first out): you push and pop at the same end and read the element with top(). A queue is FIFO (first in, first out): you push at the back, pop from the front, and read it with front(). Both are container adapters in the STL.Why does pop() not return the element in C++ STL?
pop() returns void for safety: if copying the removed element threw an exception after it had already been removed, the value would be lost. So you read the element first with top() or front(), then call pop().How do I make a min-heap priority_queue in C++?
priority_queue is a max-heap. For a min-heap write std::priority_queue<int, std::vector<int>, std::greater<int>> pq; so top() returns the smallest element.Which container does std::stack use internally?
stack and queue use std::deque, and priority_queue uses std::vector. You can choose another underlying container, for example std::stack<int, std::vector<int>>.