std::stack и std::queue в C++: стек и очередь на практике
Поисковый запрос, под который написана эта статья: std::stack и std::queue в C++ примеры. Эти контейнеры часто встречаются в учебных задачах, алгоритмах, очередях обработки событий, обходе графов и моделировании процессов. Главное отличие от обычного std::vector в том, что стек и очередь специально ограничивают доступ к элементам, чтобы код лучше отражал логику задачи.
Что такое стек и очередь простыми словами
std::stack — это стек. Он работает по принципу LIFO: Last In, First Out, то есть «последним пришёл — первым вышел». Представьте стопку тарелок: последнюю положили сверху, её же первой и возьмёте.
std::queue — это очередь. Она работает по принципу FIFO: First In, First Out, то есть «первым пришёл — первым вышел». Как обычная очередь в магазине: кто пришёл раньше, обслуживается раньше.
Как подключить std::stack и std::queue
Для стека нужен заголовок <stack>, для очереди — <queue>. Оба контейнера находятся в пространстве имён std.
#include <iostream>
#include <stack>
#include <queue>
int main() {
std::stack<int> numbersStack;
std::queue<int> numbersQueue;
return 0;
}
std::stack в C++: основные методы
У std::stack есть несколько базовых операций:
- push(value) — добавить элемент наверх стека;
- pop() — удалить верхний элемент;
- top() — получить верхний элемент;
- empty() — проверить, пуст ли стек;
- size() — узнать количество элементов.
#include <iostream>
#include <stack>
int main() {
std::stack<int> st;
st.push(10);
st.push(20);
st.push(30);
std::cout << "Верхний элемент: " << st.top() << '\n';
st.pop();
std::cout << "После pop(): " << st.top() << '\n';
std::cout << "Размер стека: " << st.size() << '\n';
return 0;
}
Вывод будет таким: сначала 30, потом 20, потому что стек возвращает элементы в обратном порядке добавления.
Важная ошибка: pop() не возвращает элемент
Новички часто ожидают, что pop() вернёт удалённое значение. В C++ это не так: pop() только удаляет элемент. Если значение нужно сохранить, сначала вызовите top(), а затем pop().
int value = st.top();
st.pop();
std::cout << "Удалили: " << value << '\n';
Практический пример std::stack: проверка скобок
Классическая задача для стека — проверить, правильно ли расставлены скобки в строке. Каждый раз, когда встречаем открывающую скобку, кладём её в стек. Когда встречаем закрывающую — проверяем верхний элемент.
#include <iostream>
#include <stack>
#include <string>
bool isValidBrackets(const std::string& text) {
std::stack<char> st;
for (char ch : text) {
if (ch == '(' || ch == '[' || ch == '{') {
st.push(ch);
} else if (ch == ')' || ch == ']' || ch == '}') {
if (st.empty()) {
return false;
}
char open = st.top();
st.pop();
if ((ch == ')' && open != '(') ||
(ch == ']' && open != '[') ||
(ch == '}' && open != '{')) {
return false;
}
}
}
return st.empty();
}
int main() {
std::cout << isValidBrackets("{[()]}") << '\n'; // 1
std::cout << isValidBrackets("{[(])}") << '\n'; // 0
}
std::queue в C++: основные методы
У std::queue логика другая: элементы добавляются в конец, а извлекаются из начала.
- push(value) — добавить элемент в конец очереди;
- pop() — удалить первый элемент;
- front() — получить первый элемент;
- back() — получить последний элемент;
- empty() — проверить, пуста ли очередь;
- size() — узнать размер очереди.
#include <iostream>
#include <queue>
int main() {
std::queue<std::string> tasks;
tasks.push("Скачать файл");
tasks.push("Обработать данные");
tasks.push("Сохранить результат");
std::cout << "Первая задача: " << tasks.front() << '\n';
std::cout << "Последняя задача: " << tasks.back() << '\n';
tasks.pop();
std::cout << "Теперь первая: " << tasks.front() << '\n';
return 0;
}
Практический пример std::queue: обработка заявок
Очередь удобно использовать, когда нужно обработать элементы строго в порядке поступления: заявки пользователей, события, сообщения, задачи фонового обработчика.
#include <iostream>
#include <queue>
#include <string>
int main() {
std::queue<std::string> requests;
requests.push("Заявка #101");
requests.push("Заявка #102");
requests.push("Заявка #103");
while (!requests.empty()) {
std::string current = requests.front();
requests.pop();
std::cout << "Обрабатываем: " << current << '\n';
}
return 0;
}
Нельзя обращаться к top(), front() и back() у пустого контейнера
Перед вызовом top(), front() или back() всегда проверяйте контейнер через empty(). Обращение к элементу в пустом стеке или очереди приводит к неопределённому поведению.
if (!tasks.empty()) {
std::cout << tasks.front() << '\n';
}
Чем std::stack и std::queue отличаются от vector
std::stack и std::queue — это не самостоятельные контейнеры в привычном смысле, а контейнерные адаптеры. Они используют другой контейнер внутри, чаще всего std::deque, но дают ограниченный интерфейс.
Если вам нужен доступ к элементам по индексу, сортировка или проход по всем элементам — берите std::vector или другой подходящий контейнер. Если же задача описывается словами «взять последний добавленный» или «обработать в порядке поступления», тогда std::stack и std::queue делают код понятнее.
Когда использовать стек, а когда очередь
- std::stack подходит для отмены действий, проверки скобок, обхода в глубину, хранения истории переходов.
- std::queue подходит для очередей задач, обработки событий, обхода в ширину, моделирования клиентов или заявок.
Советы для новичков
- Не вызывайте pop(), если контейнер пуст.
- Помните: pop() ничего не возвращает.
- Для стека используйте top(), для очереди — front() и back().
- Не выбирайте стек или очередь «на всякий случай» — выбирайте их, когда порядок доступа действительно важен.
Если вы хотите не просто запомнить методы, а уверенно понимать контейнеры, функции, классы и алгоритмы, полезно пройти системное обучение: освоить C++ по шагам от первых программ до уверенной разработки. Такой подход помогает быстрее перейти от отдельных примеров к полноценным проектам.
Итоги
std::stack и std::queue в C++ — простые, но очень полезные инструменты. Стек работает по принципу LIFO, очередь — по принципу FIFO. Их стоит использовать там, где сама задача требует строгого порядка извлечения элементов. Проверяйте контейнер на пустоту, не ждите значения от pop() и выбирайте структуру данных под конкретную логику программы.
-
Создано 12.10.2026 17:00:32
-
Михаил Русаков

Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.