前言
本篇博客我们来看一个特殊的结构,它既有顺序表(vector)的随机访问,也可以有链表(list)高效的头插尾插,这就是双端队列(deque)
💓 个人主页:小张同学zkf
⏩ 文章专栏:C++
若有问题 评论区见📝
🎉欢迎大家点赞👍收藏⭐文章
目录
5.为什么选择deque作为stack和queue的底层默认容器
1.容器适配器
适配器是一种设计模式
(
设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设
计经验的总结
)
,
该种模式是将一个类的接口转换成客户希望的另外一个接口
。
2.STL标准库中stack和queue的底层结构
虽然
stack
和
queue
中也可以存放元素,但在
STL
中并没有将其划分在容器的行列,而是将其称为
容器适配器
,这是因为
stack
和队列只是对其他容器的接口进行了包装,
STL
中
stack
和
queue
默认
使用
deque
,比如:
![](https://i-blog.csdnimg.cn/direct/7013082d6939487884107f4a93c0d8fd.png)
3.deque的介绍
deque(
双端队列
)
:是一种双开口的
"
连续
"
空间的数据结构
,双开口的含义是:可以在头尾两端
进行插入和删除操作,且时间复杂度为
O(1)
,与
vector
比较,头插效率高,不需要搬移元素;与
list
比较,空间利用率比较高。
![](https://i-blog.csdnimg.cn/direct/593346efe3a44aa2b207dae496e61b99.png)
deque
并不是真正连续的空间,而是由一段段连续的小空间拼接而成的,实际
deque
类似于一个
动态的二维数组
,其底层结构如下图所示:
![](https://i-blog.csdnimg.cn/direct/3e855470a0d14580ab39b9f6a6d516dd.png)
双端队列底层是一段假象的连续空间,实际是分段连续的,为了维护其
“
整体连续
”
以及随机访问
的假象,落在了
deque
的迭代器身上,
因此
deque
的迭代器设计就比较复杂,如下图所示:
![](https://i-blog.csdnimg.cn/direct/04a2792fa92c44d38ce6b2797d47dd26.png)
那deque是如何借助其迭代器维护其假想连续的结构呢?
4.deque缺陷
与
vector
比较
,
deque
的优势是:头部插入和删除时,
不需要搬移元素,效率特别高
,而且在
扩
容时,也不需要搬移大量的元素
,因此其效率是比
vector
高的。
与
list
比较
,其底层是连续空间,
空间利用率比较高
,不需要存储额外字段。
但是,
deque
有一个致命缺陷:不适合遍历,因为在遍历时,
deque
的迭代器要频繁的去检测其
是否移动到某段小空间的边界,导致效率低下
,而序列式场景中,可能需要经常遍历,因此
在实
际中,需要线性结构时,大多数情况下优先考虑
vector
和
list
,
deque
的应用并不多,而
目前能看
到的一个应用就是,
STL
用其作为
stack
和
queue
的底层数据结构
。
5.为什么选择deque作为stack和queue的底层默认容器
stack
是一种后进先出的特殊线性数据结构,因此只要具有
push_back()
和
pop_back()
操作的线性
结构,都可以作为
stack
的底层容器,比如
vector
和
list
都可以;
queue
是先进先出的特殊线性数据
结构,只要具有
push_back
和
pop_front
操作的线性结构,都可以作为
queue
的底层容器,比如
list
。但是
STL
中对
stack
和
queue
默认选择
deque
作为其底层容器,主要是因为:
1. stack 和 queue 不需要遍历 ( 因此 stack 和 queue 没有迭代器 ) ,只需要在固定的一端或者两端进行操作。2. 在 stack 中元素增长时, deque 比 vector 的效率高 ( 扩容时不需要搬移大量数据 ) ; queue 中的元素增长时, deque 不仅效率高,而且内存使用率高。
结合了
deque
的优点,而完美的避开了其缺陷。
结束语
STL容器目前先总结到这里,下一篇我们对C++的模版进一步深入
OK,感谢观看!!!