C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > C++中stack和queue

C++中stack和queue正确使用方法

作者:晴天的雨.992

queue和stack是C++容器适配器,基于deque等容器封装,分别实现FIFO和LIFO语义,这篇文章主要介绍了C++中stack和queue正确使用方法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

前言

本文围绕 C++ STL 中的三种容器适配器展开:stack(栈)、queue(队列)。它们本身不是独立容器,而是对底层容器的封装与接口限制,因此理解它们的接口语义和底层容器选择,是正确使用它们的关键。

文章会逐一介绍三者的常用接口、元素进出规则,并说明为什么 stack 与 queue 默认使用 deque 作为底层容器,而 priority_queue 默认使用 vector,帮助你在实际场景中做出合适的选择。

底层:stack、queue不是容器,是容器适配器,默认底层用 deque stack:LIFO 后进先出 queue:FIFO 先进先出

为什么默认用 deque 作为底层容器

deque 是双端队列,在头部和尾部插入、删除元素都是常数时间复杂度,而且不需要像 vector 那样在扩容时整体搬移已有元素,因此 stack 的 push/pop 和 queue 的入队/出队都能稳定地保持高效。

从内存角度看,deque 由多段固定大小的缓冲区拼接而成,扩容时只需新增一段缓冲区,不会一次性申请大块连续内存,也不会产生大量元素拷贝,内存增长更平滑。

相比之下,vector 要求元素在内存中连续存放,尾部操作虽然也是均摊常数时间,但一旦容量不足就要重新申请更大的连续空间并搬移全部元素,而头部插入删除更是 O(n) 的整体移动,对 queue 的队首弹出很不友好。

结论:需要双端高效操作、又不要求随机访问和内存连续性时,deque 是 stack 与 queue 更合适的默认底层容器;vector 更适合只在尾部操作、且看重连续内存与缓存友好的场景(例如 priority_queue)。

stack<int> s1
接口作用
push(val)入栈,压到栈顶
pop()弹出栈顶元素,不返回值
top()返回栈顶元素引用(不会删除)
empty()判断是否为空,空返回 true
size()返回栈中元素个数

stack没有迭代器,不能遍历!只能操作栈顶。

template< class T, class Container = deque<T> > 
class stack;
stack<int> s1;
s1.push(1);
s1.push(2);
cout << st.top(); // 2
s1.pop();
cout << st.top(); // 1

栈不能遍历!

stack 没有迭代器,不能 for 循环遍历,只能不断 top+pop。

queue 队列

template< class T, class Container = deque<T> > 
class queue;

底层默认容器:deque

queue<int> q;

常用接口

表格

函数作用
push(x)入队,加到队尾
pop()弹出队首(不返回元素)
front()返回队首元素
back()返回队尾元素
empty()是否为空
size()元素数量

同样:pop () 只删除,不返回值

queue<int> q;
q.push(1);
q.push(2);
cout << q.front(); // 1
q.pop();
cout << q.front(); // 2

queue 也没有迭代器,不能直接遍历。

容器规则取元素位置删除位置底层默认
stackLIFO 后进先出top () 栈顶pop () 栈顶deque
queueFIFO 先进先出front () 队首pop () 队首deque
priority_queue按优先级top () 最值pop () 最值vector

stack 和 queue 叫容器适配器(container adapter) 它们本身不是独立容器,只是封装了 deque/vector,限制接口,只留下栈 / 队列行为。

总结

面试高频细节问答

Q1:为什么 stack 和 queue 默认用 deque?

deque 头尾增删 O (1),连续分段内存,扩容开销优于 vector;stack 只用尾部,queue 头尾都要用。vector 头部删除不行,list 随机访问差、内存碎片多。

Q2:为什么 priority_queue 底层默认 vector?

堆是完全二叉树,适合用连续数组存储,下标计算父子节点很方便,vector 连续内存缓存友好。

Q3:可以用 stack 遍历全部元素吗?

只能 top+pop 依次拿,拿出来就删掉;如果想要保留数据,要全部 pop 出来存到别的容器再装回去。

Q4:为什么 stack、queue 不提供迭代器?

设计目的是限制访问,只暴露栈 / 队列接口,保证 LIFO/FIFO 语义;如果开放迭代器,就可以随意修改中间元素,破坏抽象。

Q5:空容器调用 top/front/back/pop 会抛异常吗?

不会抛异常!标准规定是 UB,这点和 Java 不一样,Java 会抛异常。必须手动 empty 判断。

到此这篇关于C++中stack和queue正确使用方法的文章就介绍到这了,更多相关C++中stack和queue内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文