一、基本原理
除了顺序容器外,标准库还提供了三种容器适配器(container adapter):栈stack、队列queue、优先队列priority_queue。stack和queue基于deque实现,priority_queue基于vector实现。限于篇幅,本篇博客只介绍stack和queue。
什么是容器适配器呢?
假设我需要一个栈结构,可以用deque来模拟,只在一端进行元素插入和弹出,另一端不动,但我不能防止别人在deque的另一端进行操作,因此deque并不能严格地满足我的要求。我对它进行封装,作一些限制,使它留出的接口只能在一端进行插入和删除,这样就实现了stack。
实际上stack底层是使用的deque,只是对deque进行了封装改变了对外的接口而已。因此,stack、queue、priority_queue一般称为容器适配器,它们只是基本容器类型(vector、deque、list等)的适配。
二、用法
以下都以容器中的元素为int为例,若要保存其他类型的元素,将int换成其他类型即可。
初始化
stack | stack<类型名> 栈名; |
---|---|
stack<int> s1; | 创建一个名为s1的空堆栈,s1中的元素类型为int |
stack<int> s2(s1); | 堆栈s2中包含和堆栈s1一样的元素 |
stack<int> s2=s1; | 堆栈s2中包含和堆栈s1一样的元素 |
stack<int> s2(d1); | 堆栈s2中包含和双端队列d1一样的元素,d1的类型为deque |
queue | queue<类型名> 队列名; |
---|---|
queue<int> q1; | 创建一个名为q1的空单端队列,q1中的元素类型为int |
queue<int> q2(q1); | 单端队列q2中包含和单端队列q1一样的元素 |
queue<int> q2=q1; | 单端队列q2中包含和单端队列q1一样的元素 |
queue<int> q2(d1); | 单端队列q2中包含和双端队列d1一样的元素,d1的类型为deque |
其他
stack | |
---|---|
s1.top(); | 返回堆栈的栈顶元素 |
s1.pop(); | 栈顶元素出栈 |
s1.push(e); | 元素e入栈 |
s1.emplace(e); | 元素e入栈 |
s1.empty(); | 堆栈为空则返回true,否则返回false |
s1.size(); | 堆栈的大小 |
s1.swap(s2); | 交换s1、s2的元素 |
queue | |
---|---|
q1.front(); | 返回单端队列的队首元素 |
q1.back(); | 返回单端队列的队尾元素 |
q1.pop(); | 队首元素出队 |
q1.push(e); | 添加元素e到队尾 |
q1.emplace(e); | 添加元素e到队尾 |
q1.empty(); | 单端队列为空则返回true,否则返回false |
q1.size(); | 单端队列的大小 |
q1.swap(q2); | 交换q1、q2的元素 |
容器适配器不支持迭代器
容器 | 迭代器 |
---|---|
vector | 随机访问 |
string | 随机访问 |
deque | 随机访问 |
array | 随机访问 |
list | 双向 |
forward_list | 单向 ,只能++不能- - |
set/multiset | 双向 |
map/multimap | 双向 |
unordered_set/unordered_multiset | 双向 |
unordered_map/unordered_multimap | 双向 |
stack | 不支持迭代器 |
queue | 不支持迭代器 |
priority_queue | 不支持迭代器 |
三、程序举例
#include <iostream>
#include <queue>
#include <stack>
using namespace std;
int main() {
deque<int> d1{ 1,2 }; // 创建一个双端队列,元素为1,2
stack<int> s1(d1); // 用双端队列来初始化栈
stack<int> s2; // 创建一个空栈
int a = s1.top(); // 栈顶元素a=2
s1.pop(); // 元素2出栈
s1.push(3); // 3入栈,s1元素为1,3
int size = s1.size(); // s1的大小为2
s1.swap(s2); // 交换s1和s2的所有元素
queue<int> q1(d1); // 用双端队列来初始化单端队列
queue<int> q2; // 创建一个空队列
int f = q1.front(); // 队首元素f=1
int b = q1.back(); // 队尾元素b=2
q1.pop(); // 队首元素出队
q2.push(3); // 入队,队列元素为2,3
int size2 = q1.size(); // 队列的大小
q1.swap(q2); // 交换q1和q2所有元素
}