一.概述
C++ 中的 std::stack 是一种容器适配器,提供了一种后进先出(LIFO, Last In First Out)的数据结构。它只允许在栈顶进行插入和删除操作,不支持随机访问。
主要特性:
- 后进先出(LIFO):最后插入的元素最先被访问或移除。
- 栈顶操作:只能在栈顶插入、访问和移除元素。
- 受限接口:std::stack 只提供插入、删除、访问栈顶、检查大小和判断是否为空等基本操作,不支持像 std::vector 这样的随机访问。
二.初始化
2.1头文件
#include <stack>
2.2初始化
stack支持多种初始化方式,默认使用deque作为底层容器。
stack<int> s1; //默认构造
stack<int> s2(s1); //拷贝构造,使用s1初始化s2
stack<int> s3(move(s1)); // 使用移动语义初始化s3
stack<int, vector<int>> s4; //使用vector作为底层容器
stack<int, list<int>> s5; //使用list作为底层容器vector<int> vec = {1, 2, 3, 4, 5};
stack<int, vector<int>> s6(vec); //使用已有的vector初始化deque<int> deq = {6, 7, 8, 9, 10};
stack<int, deque<int>> s7(deq); //使用已有的deque初始化
三.成员函数
接口 | 含义 |
---|---|
top() | 访问栈顶元素。 |
size() | 返回栈中元素的个数。 |
empty() | 判断栈是否为空。如果栈为空,返回 true,否则返回 false。 |
pop() | 移除栈顶元素。 |
push() | 将元素压入栈顶。 |
swap(stack& other) | 交换两个栈的内容,两个栈必须具有相同的类型和底层容器。 |
四.遍历
4.1 破坏性的
通过 pop() 操作来访问每个栈顶元素并将其移除。
#include <iostream>
#include <stack>using namespace std;int main() {stack<int> s;s.push(10);s.push(20);s.push(30);while (!s.empty()) {cout << s.top() << " "; // 访问栈顶元素s.pop(); // 移除栈顶元素}return 0;
}/*
output:30 20 10
*/
4.2 非破坏性的
为了不破坏原始栈,可以使用一个辅助栈来保存遍历时的内容。遍历时将元素从原栈弹出到辅助栈,遍历完成后再将元素从辅助栈弹回原栈。
#include <iostream>
#include <stack>using namespace std;int main() {stack<int> s;s.push(10);s.push(20);s.push(30);stack<int> temp; // 辅助栈while (!s.empty()) {cout << s.top() << " "; // 访问栈顶元素temp.push(s.top()); // 存入辅助栈s.pop(); // 从原栈中移除}cout << endl;// 将元素从辅助栈移回原栈,恢复原始状态while (!temp.empty()) {s.push(temp.top());temp.pop();}return 0;
}/*
output:30 20 10
*/
4.3 使用底层容器遍历(不推荐)
stack能够基于deque、vector 或list构建。可以通过访问栈的底层容器来实现遍历,前提是需要了解依赖的具体底层容器类型。
注:可能会因为编译器问题导致出错(不能直接访问它的底层容器(如 c),因为受到了protected访问控制限制),那就参考4.4或者4.5的方法
#include <iostream>
#include <stack>
#include <deque>using namespace std;int main() {stack<int, deque<int>> s; // 使用deque作为底层容器s.push(10);s.push(20);s.push(30);// 通过底层容器的迭代器进行遍历for (auto it = s.c.begin(); it != s.c.end(); ++it) {cout << *it << " ";}return 0;
/*
output:10 20 30
*/
}
4.4 使用deque来模拟栈,并遍历:
#include <iostream>
#include <deque>using namespace std;int main() {// 使用 std::deque 模拟栈deque<int> deq;// 向 "栈" 中推入元素deq.push_back(10);deq.push_back(20);deq.push_back(30);// 遍历 deque (从栈底到栈顶)for (auto it = deq.begin(); it != deq.end(); ++it) {cout << *it << " ";}cout << endl;// 模拟栈顶操作(访问最后一个元素)cout << "栈顶元素是: " << deq.back() << endl;// 模拟弹出栈顶元素deq.pop_back(); // 移除栈顶元素cout << "弹出栈顶元素后,新的栈顶是: " << deq.back() << endl;return 0;
}
/*
output:
10 20 30
栈顶元素是: 30
弹出栈顶元素后,新的栈顶是: 20
*/
4.5 自定义栈类
标准库不允许直接访问stack的底层容器,但可以通过继承stack来扩展它并提供对底层容器的访问接口。
#include <iostream>
#include <stack>
#include <deque>using namespace std;// 自定义继承 std::stack 的类
template<typename T>
class MyStack : public stack<T> {
public:// 提供底层容器的访问接口typename deque<T>::iterator begin() {return this->c.begin();}typename deque<T>::iterator end() {return this->c.end();}
};int main() {// 使用自定义栈MyStack<int> s;s.push(10);s.push(20);s.push(30);// 遍历底层容器cout << "栈中的元素(从底到顶):" << endl;for (auto it = s.begin(); it != s.end(); ++it) {cout << *it << " ";}return 0;
}
/*
output:10 20 30
*/