C++中stack和queue默认的底层实现容器是deque
理论讲解:代码随想录
Leetcode链接:
232. 用栈实现队列:力扣
225. 用队列实现栈:力扣
栈和队列
queue的取队头元素的函数为front()
栈与队列的底层实现:
C++中stack和queue默认的底层实现容器是deque,deque里元素并不是严格的连续分布
deque是一个双向队列。
栈是以底层容器完成其所有的工作,对外提供统一的接口,底层容器是可插拔的(也就是说我们可以控制使用哪种容器来实现栈的功能)。
所以STL中栈往往不被归类为容器,而被归类为container adapter(容器适配器)。栈的底层实现可以是vector,deque,list , 主要就是数组和链表的底层实现。
std::stack<int, std::vector<int> > third; // 使用vector为底层容器的栈
std::queue<int, std::list<int>> third; // 定义以list为底层容器的队列
可以出一道面试题:栈里面的元素在内存中是连续分布的么?
这个问题有两个陷阱:
- 陷阱1:栈是容器适配器,底层容器使用不同的容器,导致栈内数据在内存中是不是连续分布。
- 陷阱2:缺省情况下,默认底层容器是deque,那么deque的在内存中的数据分布是什么样的呢? 答案是:不连续的,下文也会提到deque。
std::deque
double-ended queue,双向队列,可以向两端扩展。
deque有不同的实现方式,通常是某种类型的动态数组,允许随机访问迭代器直接访问单个元素,自动扩展和收缩容器大小,在序列的开头和结尾处提供相对快速的增加和删除。
deque的元素不连续存储,可以分布在不同的块中,因此不能用指针+偏移访问。
232. 用栈实现队列
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push
、pop
、peek
、empty
):
解法:
两个栈实现队列,不妨假设栈B为输出栈,即栈B的输出需要符合队列的输出,即栈B要实现后来到的先入栈。
栈A为中间保存栈,每当新元素到达时,将栈B中所有元素移入A,然后将新元素移入B,再将栈A中所有元素移入B。
- 如到达顺序为1234,4到达时,栈A为空,栈B中由栈顶到栈底为123
- B中所有元素移入A,栈A中栈顶到栈底为321
- 新到来的元素4移入B,A中所有元素移入B,栈B中栈顶到栈底为1234
- 如果需要输出,则直接从B中输出,符合队列的FIFO原则
225. 用队列实现栈
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push
、top
、pop
和 empty
)。
解法:
类似用栈实现队列,使用一个输入队列一个输出队列
queue的取队头元素的函数为front