C++的STL学习 9 : 容器适配器的认识和 deque(双端队列)的基本认识

之前我们学习了STL的几个容器: string, vector, list. 今天我们来看容器适配器: stack(栈), queue(队列), priority_queue(优先级队列). 这次我们谈谈适配器的思想和 stack的使用和实现. 那么话不多说, 直入主题, 耐心看完, 你一定有所收获~

一. 适配器的理解

适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),该种模式是将一个类的接口转换成客户希望的另外一个接口。

打个比方就是充电器, 给手机充电肯定不能直接连家里220V的电源吧…这时候就需要适配器, 把220V的电压转换成需要的电压值, 供给人们使用

拿栈stack来举个例子, 只要能满足栈的操作的容器都可以用来实现栈, 比如vector, list, deque都可以实现stack, 我们拿vector来说, vector提供了很多的操作, 但是stack实现的操作很少, 那么我只需要将vector封装成stack, 把stack需要的操作暴露出来就可以了, 其他操作不暴露出来. 这样就完成了一个容器适配器.

二. deque的简单认识

deque(双端队列):是一种双开口的"连续"空间的数据结构

双开口的含义是:可以在头尾两端进行插入和 删除操作,且时间复杂度为O(1),与vector比较,头插效率高,不需要搬移元素;与list比较,空间利用率比较高。

要注意的是 : 双端队列deque是原生实现的容器, 但他一般都作为其他容器适配器的底层容器, 而不作为容器单独使用

下面我们来简单了解一下deque 的结构, 这里不做过深的解释, 原理比较复杂, 感兴趣的小伙伴可以去查阅相关资料…

deque并不是真正连续的空间,而是由一段段连续的小空间拼接而成的,实际deque类似于一个动态的二维数组

其底层结构如下图所示:

在这里插入图片描述
双端队列底层是一段假象的连续空间,实际是分段连续的,为了维护其“整体连续”以及随机访问的假象,落 在了deque的迭代器身上

因此deque的迭代器设计就比较复杂,如下图所示:

在这里插入图片描述

具体的关系如下图所示:
在这里插入图片描述

简单总结一下:

deque可以实现头插, 头删, 尾插, 尾删
它并不是真正的连续空间, 而是一个指针数组, 每个指针指向一个连续空间
deque从中间开始存放数据, 当前缓冲区装满之后新开辟空间, 新开辟空间时, 头插在末尾, 尾插在头部, 保证数据的逻辑连续性

deque的优缺点:

与vector比较,deque的优势是
头部插入和删除时,不需要搬移元素,效率特别高,而且在扩容时,也不需要搬移大量的元素,因此其效率是必vector高的。

与list比较
其底层是连续空间,空间利用率比较高,不需要存储额外字段。

而他的缺点也很明显
不适合遍历因为在遍历时,deque的迭代器要频繁的去检测其是否移动到 某段小空间的边界,导致效率低下

而序列式场景中,可能需要经常遍历,

因此在实际中,需要线性结构时,大多数情况下优先考虑vector和list

deque的应用并不多,而目前能看到的一个应用就是,STL用其作 为stack和queue的底层数据结构

我们说deque是一种比较中庸的容器, 因为他的随机访问效率低于vector, 插入效率低于list. 这也是deque容器的结构所致的, 有得有失.

没有最好的容器, 只有最合适的场景

下面我们来看看为什么stack和queue使用deque作为默认底层实现容器呢 ?

stack是一种后进先出的特殊线性数据结构,因此只要具有push_back()和pop_back()操作的线性结构,都可 以作为stack的底层容器,比如vector和list都可以;
queue是先进先出的特殊线性数据结构只要具有 push_back和pop_front操作的线性结构,都可以作为queue的底层容器,比如list。 (vector不能实现queue, 因为vector不提供pop_front操作)
但是STL中对stack和 queue默认选择deque作为其底层容器,主要是因为:

  1. stack和queue不需要遍历(因此stack和queue没有迭代器),只需要在固定的一端或者两端进行操作。
  2. 在stack中元素增长时,deque比vector的效率高(扩容时不需要搬移大量数据);queue中的元素增长时,deque不仅效率高,而且deque是连续空间, 内存使用率高。
    结合了deque的优点,而完美的避开了其缺陷。

OK, 容器适配器和deque就说到这里, 下次我们就看看几种容器适配器的使用和实现.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

殇&璃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值