C++容器适配器【困难篇】双向队列详解

前面我们一直说什么是容器适配器,那本片博客带你来揭晓容器适配器、deque和优先级队列。


容器适配器

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

迭代器也是一种设计模式

扩展知识设计模式有20多种类
创建型模式 (5 种)

1.单例模式 Singleton

2.工厂方法模式 Factory Method

3.抽象工厂模式 Abstract Factory

4.建造者模式 Builder

5.原型模式 Prototype


结构型模式 (7 种)

  1. 适配器模式 Adapter

  2. 桥接模式 Bridge

  3. 组合模式 Composite

  4. 装饰模式 Decorator

  5. 外观模式 Facade

  6. 享元模式 Flyweight

  7. 代理模式 Proxy


行为型模式 (11 种)

13.责任链模式 Chain of Responsibility

  1. 命令模式 Command

  2. 解释器模式 Interpreter

  3. 迭代器模式 Iterator

  4. 中介者模式 Mediator

  5. 备忘录模式 Memento

  6. 观察者模式 Observer

  7. 状态模式 State

  8. 策略模式 Strategy

  9. 模板方法模式 Template Method

  10. 访问者模式 Visitor

我们目前了解一下就好


STL标准库中stack和queue的底层结构

虽然stack和queue中也可以存放元素,但在STL中并没有将其划分在容器的行列,而是将其称为容器适配器,这是因为stack和队列只是对其他容器的接口进行了包装,STL中stack和queue默认使用deque,比如:



双端队列(deque)

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

deque就是一个中控数组

如下图:

双端队列底层是一段假象的连续空间,实际是分段连续的,为了维护其"整体连续"以及随机访问的假象,落在了deque的迭代器身上,因此deque的迭代器设计就比较复杂,我们先看源码。

我们迭代器是由四个部分构成的。简单来说是四个指针

这个buff就是数组,目前不管有多大。

为啥是中控数组因为要头插数据,如果要向随机迭代器那样访问元素。

如下图:


我们两个迭代器(begin,end)一个指向第一个buff,另一个指向最后一个buff

里面的四个指针也分别指向四个元素。头插就让node减减,开辟新的buff,然后从buff的从末尾往前插入数据。为啥呢,避免头插浪费资源,那迭代器还能随机吗?

能!他是传了一个变量n,让n+(cur-fast)。来进行访问,来看看源码如下图:

他就是个指针数组,用来存放指针。


deque的缺陷

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

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

但是,deque有一个致命缺陷:不适合遍历,因为在遍历时,deque的迭代器要频繁的去检测其是否移动到某段小空间的边界,导致效率低下,而序列式场景中,可能需要经常遍历,因此在实际中,需要线性结构时,大多数情况下优先考虑vector和list,deque的应用并不多,而目前能看到的一个应用就是,STL用其作为stack和queue的底层数据结构。

为什么选择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的优点,而完美的避开了其缺陷。
相关推荐
程序猿追3 小时前
kotlin-retry 接入鸿蒙后,怎样确认它真的会停止重试
开发语言·kotlin·harmonyos
我是人✓3 小时前
Java文件上传三方式对比:从传统到SpringBoot
java·开发语言
智能直播3 小时前
网络RTMP拉流不卡顿、声音不同步,一文讲透缓冲区、时间戳
开发语言·ffmpeg·php·音视频·视频编解码
墨云安全4 小时前
内网资产无法暴露到公网,怎么做安全检测?2026 年内网渗透测试的落地路径
开发语言·安全·网络安全·渗透测试·php
摇滚侠4 小时前
《计算机是如何工作的:人人都能懂的计算机软硬件工作原理》第 9 章 机器码与汇编语言 阅读笔记 9
java·开发语言·笔记
Cc.Y4 小时前
Java零基础入门:深入Java核心:文件IO与序列化全解
java·开发语言·python
xier_ran4 小时前
【infra之路】AI 编译器学习笔记(六):重拾 C++——lambda 与 MLIR 中的回调
c++·笔记·学习
jimy16 小时前
c++的 Type Traits (一)
开发语言·c++
别动我齐刘海6 小时前
Linux 系统调试学习2
linux·运维·c++·人工智能·学习·机器学习·机器人
Web极客码6 小时前
Python Ollama 本地 Agent 入门与订单查询实践
开发语言·jvm·python