栈和队列也是只对用法做简单介绍,后面还会有priority_queue的介绍与使用,priority_queue是优先级队列,可以理解为堆。需要提前了解的是栈和队列并没有迭代器,他们是容器适配器。
一.容器适配器
适配器是一种设计模式,设计模式则是一套被反复使用的,多数人知晓的,经过分类编目,代码设计经验的总结。简单来说就是把一个类的接口转化为用户所希望的接口,是在已有的类的基础上封装衍生出来的。而栈和队列的底层是deque(默认的是),栈和队列对其进行了包装。
二.deque

可以如图所示理解deque的底层,可以想象成一个二维数组,但是每一层都是可以改变大小的,因为有许多层,每层的长度也不算太大这使得deque的插入删除效率比起完整的特别长的数组效率提高。deque实际上是一种双端队列,每一个节点存储的是一个个单独数组的(即前面说的每一层)地址,并且deque的成员有四个分别指向队列节点,数组的开头和结尾,数组中实际使用的节点位置,这些比较复杂,想要了解的可以自行查询。
deque的优点在于头尾插入删除效率比vector高,空间利用率比较高。但是deque在遍历时效率非常底下,因为需要比较是否到达每一层的最后一个,然后过完了这一层去下一层还需要改变四个成员的指向,因此一般需要线性结构遍历的时候一般用vector或list,而deque的应用并不多。
stack和queue没有迭代器不需要遍历,所以选择deque,因为选择vector的话插入删除在数据量特别大的时候效率非常低下,并且两者都是只需要头尾插入删除的操作。
三.栈
首先是栈的使用,先看表
|----------|----------|
| 函数说明 | 接口说明 |
| stack() | 构造空的栈 |
| empty() | 检查是否为空 |
| size() | 返回栈中数据个数 |
| top() | 返回栈顶元素 |
| push() | 把元素压入栈中 |
| pop() | 弹出栈顶元素 |
四.队列
看表
|----------|----------|
| 函数声明 | 接口说明 |
| queue() | 构造空的队列 |
| empty() | 检查是否为空 |
| size() | 返回队列数据个数 |
| front() | 返回队头元素 |
| back() | 返回队尾元素 |
| push() | 插入元素 |
| pop() | 删除元素 |
五.priority_queue
priority_queue可以理解为堆,也是容器适配器的一种,默认适配容器是vector<T>,默认大堆。可以随时插入删除元素,并且只能访问堆顶的数据(最大的那个)。下面是priority_queue的参数,第一个参数是要存储的参数类型,第二个代表仿函数,一般不用传,用来比较第一个参数的大小形式,一般默认是大堆那样的排序,第一个参数如果是内置类型,可以传greater来改变成小堆。如果第一个参数是自定义类型,就需要我们传第二个参数来确定比较的方式。
默认情况下,如果没有传参指定使用什么容器,一般用vector。如果传了其他的,想要用其他的容器来实现,就需要确保这个容器可以支持随机访问迭代器(operator[ ]),因为需要确保堆的结构。并且还需要这种容器支持以下操作:
empty(),size(),front(),push_back(),pop_back()
下面是priority_queue的使用
|------------------|-----------------|
| 函数说明 | 接口说明 |
| priority_queue() | 构造空的优先级队列 |
| empty() | 检测是否为空 |
| top() | 返回最大,最小元素(堆顶元素) |
| push() | 添加元素 |
| pop() | 删除元素 |