Introduction
Many problems are really about the order in which waiting items are handled. The standard library has a ready-made container for each common order, and using the right one often makes a hard problem easy.
How it works
| Container | Add | Look | Remove | Order |
|---|---|---|---|---|
stack<T> | push | top | pop | last in, first out |
queue<T> | push | front | pop | first in, first out |
priority_queue<T> | push | top | pop | largest first |
deque<T> | push_front, push_back | front, back | pop_front, pop_back | both ends |
Notice that pop removes an item but does not return it, so read it with top or front first. Calling those on an empty container is undefined behaviour, so check empty().
Priority queues keep their largest item ready. They are built on a heap, so each push and pop is cheap even with many items:
#include <iostream>
#include <queue>
using namespace std;
int main() {
priority_queue<int> tasks;
tasks.push(3);
tasks.push(9);
tasks.push(5);
while (!tasks.empty()) {
cout << tasks.top() << " ";
tasks.pop();
}
cout << endl;
return 0;
}pair holds two values, reached as .first and .second. Pairs compare by their first value and then by their second, which makes them convenient to sort.
pair<int, string> p = make_pair(3, string("Mitu"));
Syntax
stack<int> s;
s.push(1);
if (!s.empty()) {
int top = s.top();
s.pop();
}
Example
#include <iostream>
#include <queue>
#include <stack>
#include <string>
using namespace std;
int main() {
stack<string> pages;
pages.push("home");
pages.push("news");
cout << pages.top() << endl;
pages.pop();
cout << pages.top() << endl;
queue<string> line;
line.push("Mitu");
line.push("Rafi");
cout << line.front() << " " << line.size() << endl;
return 0;
}Line by line
pagesis a stack, like the Back button of a browser.- After two pushes,
topshows the newest,news. popremoves it, sotopthen showshome.lineis a queue, and people join at the back.frontshows the person who joined first.
Expected result
news
home
Mitu 2
In the real world
Stacks handle Undo and expression evaluation. Queues hold print jobs and messages between programs. Priority queues decide which task an operating system runs next, and they power the shortest-path algorithms in map apps.
Common mistakes
- Expecting
popto return the value. - Calling
toporfronton an empty container. - Expecting a
priority_queueto give the smallest first. By default it gives the largest. - Using a
vectoras a queue, which moves every element each time you remove the first.
Best practices
- Pick the container that matches the order you need.
- Always check
empty()before you remove. - Use
dequewhen you need to work at both ends.
Summary
stack is last in, first out, and queue is first in, first out. priority_queue gives the largest first. pop does not return a value, so read first, and check for empty.
Quick check
Key takeaways
- Choose a container for the order in which you need things.
- Check for empty before top, front or pop.
- A priority_queue gives its largest element first.
Practice problems for this lesson
My notes
Write down what you want to remember from this lesson. Notes are saved on this device as you type, and appear on your dashboard.