一.概述
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
*/