C++ std::stack
详细使用指南
std::stack
是 C++ 标准模板库(STL)中的一个 容器适配器,基于其他序列容器(默认为 std::deque
)实现,提供 后进先出(LIFO) 的数据结构。它适用于需要快速存取栈顶元素的场景,如函数调用管理、括号匹配、表达式求值等。
1. 基本特性
特性 | 说明 |
---|---|
底层容器 | 默认使用 std::deque ,也可选择 std::vector 或 std::list |
操作限制 | 仅允许在栈顶进行插入(push )和删除(pop )操作,不支持随机访问或遍历 |
时间复杂度 | 所有操作均为 O(1)(底层容器决定具体性能) |
内存分配 | 动态扩展(如 std::vector 底层可能触发扩容) |
2. 头文件与声明
#include <stack> // 必须包含此头文件 // 声明语法 std::stack<T> s; // 默认底层容器为 deque std::stack<T, Container> s; // 指定底层容器(如 vector/list)
• T
:存储元素的类型。
• Container
:满足序列容器要求的类型,需提供 push_back()
、pop_back()
和 back()
方法。
3. 基本操作
(1) 栈顶与栈底操作
std::stack<int> s; s.push(10); // 栈顶插入元素 s.push(20); s.push(30); cout << s.top() << endl; // 输出 30(栈顶元素) cout << s.size() << endl; // 输出 3(元素数量)
(2) 元素增删
s.pop(); // 移除栈顶元素(不返回值) if (!s.empty()) { int val = s.top(); // 安全访问栈顶元素 }
(3) 容量与状态
cout << "栈是否为空: " << (s.empty() ? "是" : "否") << endl; cout << "栈大小: " << s.size() << endl;
4. 底层容器选择std::stack
的性能和内存特性受底层容器影响:
底层容器 | 特点 | 适用场景 |
---|---|---|
std::deque (默认) | 双端队列,支持高效头尾操作 | 通用场景,平衡性能 |
std::vector | 动态数组,内存连续 | 需要紧凑内存布局的场景 |
std::list | 双向链表,无扩容开销 | 频繁插入/删除的动态场景 |
示例:使用 std::vector
作为底层容器
std::stack<int, std::vector<int>> vec_stack;
vec_stack.push(100); vec_stack.push(200);
5. 实际应用场景
(1) 括号匹配
#include <stack> #include <string> bool isBalanced(const std::string& expr) { std::stack<char> s; for (char ch : expr) { if (ch == '(' || ch == '{' || ch == '[') { s.push(ch); } else if (ch == ')' || ch == '}' || ch == ']') { if (s.empty()) return false; char top = s.top(); if ((ch == ')' && top != '(') || (ch == '}' && top != '{') || (ch == ']' && top != '[')) { return false; } s.pop(); } } return s.empty(); }
(2) 函数调用栈
// 模拟函数调用栈 std::stack<std::string> call_stack; void funcA() { call_stack.push("funcA"); funcB(); call_stack.pop(); } void funcB() { call_stack.push("funcB"); // 执行操作 call_stack.pop(); }
(3) 深度优先搜索(DFS)
std::stack<int> dfs_stack; dfs_stack.push(1); // 起始节点 while (!dfs_stack.empty()) { int node = dfs_stack.top(); dfs_stack.pop(); // 处理节点 for (int neighbor : getNeighbors(node)) { dfs_stack.push(neighbor); } }
6. 性能优化技巧
预分配内存(适用于
std::vector
底层):std::stack<int, std::vector<int>> s; s.reserve(1000); // 预分配空间,减少扩容开销
避免频繁的
pop
和push
:
若需连续访问多个元素,建议先复制到其他容器(如std::deque
)。选择合适底层容器:
• 高频插入/删除 →std::list
• 内存紧凑 →
std::vector
• 默认平衡 →
std::deque
7. 注意事项
• 空栈操作风险:调用 top()
或 pop()
前需检查 empty()
,否则触发未定义行为。
• 不可遍历:std::stack
不提供迭代器,需通过循环弹出元素访问所有内容。
• 移动语义:C++11 后支持移动构造和赋值,提升性能:
std::stack<int> s1; s1.push(10); std::stack<int> s2 = std::move(s1); // 移动而非拷贝
8. 与其他容器的对比
容器 | 访问方式 | 插入/删除位置 | 典型用途 |
---|---|---|---|
std::stack | 仅栈顶 | 栈顶 | 函数调用、括号匹配 |
std::queue | 队尾插入,队头删除 | 队尾/队头 | 任务调度、BFS |
std::deque | 双端 | 头尾 | 滑动窗口、缓冲区 |
9. 总结std::stack
是处理 后进先出场景 的高效工具,其核心优势在于:
• ✅ 简单易用,API 直观(push
/pop
/top
)。
• ✅ 底层容器灵活,适应不同性能需求。
• ✅ 时间复杂度稳定,适合高频操作。
示例代码:
#include <iostream> #include <stack> int main() { std::stack<int> s; s.push(1); s.push(2); s.push(3); while (!s.empty()) { std::cout << s.top() << " "; // 输出 3 2 1 s.pop(); } return 0; }
通过合理使用 std::stack
,可以高效解决需要栈式数据管理的实际问题。
系统当前共有 440 篇文章