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,可以高效解决需要栈式数据管理的实际问题。
系统当前共有 481 篇文章