【C++】deque的实现原理简单介绍
前言
deque被称为双端队列,它的出现主要是为了结合
vector和list的优点并减小它们的缺点,实际上deque确实结合了vector和list的优点减小了它们的缺点,但是它的结合也让它自己的优点没有原始的vector和list那么极致,导致deque变得很中庸,所以deque的应用场景也并没有那么多,它经常被用来作为stack和queue的底层容器
本篇文章我们来一起简单探讨一下deque的实现原理
deque的简单介绍
- 一、deque的原理介绍
- 二、deque的一些基本特性
- 1、deque的随机访问
- 2、deque的中间插入与删除
- 三、deque的迭代器
- 四、deque的优缺点分析
- 1、优点:
- 2、缺点:
- 五、为什么选择deque作为stack和queue的底层默认容器
一、deque的原理介绍
deque(双端队列):是一种双开口的" 连续 "空间的数据结构,双开口的含义是:可以在头尾两端进行插入和删除操作,且时间复杂度为O(1),与vector比较,头插效率高,不需要搬移元素;与list比较,空间利用率比较高,不太容易造成内存碎片。

其实deque并不是真正连续的空间,而是由一段段连续的小空间拼接而成的,实际deque类似于一个动态的二维数组,其底层结构如下图所示:

当中控数组满了,我们也只需要对中控数组进行扩容,然后拷贝指针就行了,并不需要对真正存储数据的小数组做改动,这大大减少了拷贝数据的个数。
二、deque的一些基本特性
1、deque的随机访问
deque的随机访问有两种情况: 这与deque中的小数组的大小是否固定有关。
- 假设我们
deque中的小数组是固定大小,不能进行扩容,那么我们就可以使用除模运算进行随机访问,假设想要访问的位置是 x x x,第一个数组中的元素个数是 y y y,数组的大小固定为 n n n,想要访问的小数组是从第二个数组开始第 r o w row row个,想要访问的位置在对应小数组的第 c o l col col个。
我们就可以通过 r o w = ( x − y ) / n row = (x - y)/n row=(x−y)/n c o l = ( x − y ) % n col = (x-y)\%n col=(x−y)%n从而确定我们想要访问的位置。时间复杂度是 O ( 1 ) O(1) O(1)
- 假设我们
deque的小数组可以扩容,我们的中控数组可以存放一个自定义类型,自定义类型里面有指针也有对应小数组中数据的个数。那么我们就要用从第一个数组的个数 +第二个数组的个数 +第三个数组的长度 + …直到加到某个数组时大于我们想要访问的位置,我们才能确定对应是第几个数组,然后在小数组中进行访问该元素,这样的话时间复杂度就是遍历中控数组,时间复杂度是 O ( n ) O(n) O(n)
2、deque的中间插入与删除
deque的中间插入也有两种情况: 这也与deque中的小数组的大小是否固定有关。
- 假设我们
deque中的小数组是固定大小,不能进行扩容,那么我们在中间位置进行插入或者删除时,就要移动数据,也就是说可能要把一个小数组中的数据移动到另一个小数组里。 - 假设我们
deque中的小数组是不是固定大小的。
那么我们在中间位置进行插入就可以只对当前的小数组进行扩容然后再进行插入,这样我们就不必对其他小数组中的数据进行移动了
如果我们对中间的数据进行删除,我们也只需要对当前的小数组进行缩容就进行了,如果小数组中的数据全部被删除了,那可以直接释放掉空间,然后调整中控数组就行了。
总结:deque的随机访问与deque的中间插入与删除之间有负相关的作用。当小数组固定时,随机访问效率会变高但是中间位置的插入与删除效率会变低;当小数组不固定大小时,随机访问效率会变低但是中间位置的插入与删除效率会变高。
在STL的SGI版本中对于
deque的小数组选择了固定大小,且小数组中可以存储数据的个数是8(这个大小可以通过模板参数进行调整)
三、deque的迭代器
双端队列底层是一段假象的连续空间,实际是分段连续的,为了维护其“整体连续”以及随机访问的假象,落在了deque的迭代器身上,因此deque的迭代器设计就比较复杂,如下图所示:

deque的迭代器有四个指针,第一个cur指向小数组中要指向的数据,第二个first指向小数组中的第一个位置,第三个last指向小数组中最后一个数据的下一个,第四个node反向指向中控数组,方便遍历完一个小数组后跳到下一个小数组。
四、deque的优缺点分析
1、优点:
- 与
vector比较,deque的优势是:- 头部插入和删除时,不需要搬移元素,效率特别高。
- 在扩容时,也不需要搬移大量的元素,只需要搬移中控数组中的指针就行了。
- 与
list比较,deque的优势是:- 其底层是连续空间,空间利用率比较高,不需要存储额外字段。
- 支持随机访问
2、缺点:
-
中间的插入删除与随机访问不好抉择,难以两全其美。
-
优点没有
vector和list极致,随机访问的速度没有vector快,(vector是真正的连续空间,在计算机硬件中缓存利用率极高,在排序方面这点很重要!!!),中间位置的插入与删除没有list快(list的中间位置的插入与删除是 O ( 1 ) O(1) O(1)),deque需要进行扩容,而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作为其底层容器,主要是因为:
stack和queue不需要遍历(因此stack和queue没有迭代器),只需要在固定的一端或者两端进行操作。- 在
stack中元素增长时,deque比vector的效率高(扩容时不需要搬移大量数据);queue中的元素增长时,deque不仅效率高,而且内存使用率高。两个适配器都结合了deque的优点,而完美的避开了其缺陷。
相关文章:
【C++】deque的实现原理简单介绍
前言 deque被称为双端队列,它的出现主要是为了结合vector和list的优点并减小它们的缺点,实际上deque确实结合了vector和list的优点减小了它们的缺点,但是它的结合也让它自己的优点没有原始的vector和list那么极致,导致deque变得很…...
UWB隧道人员定位技术应用,施工作业安全精准保障
隧道施工的安全不仅关系到工程项目的质量和施工效率,也关系到我国的资金安全、施工人员和人民的生命财产安全。如何有效加强隧道施工的安全管理能力,成为隧道施工企业管理者最关心的问题。国家铁道局在《关于加强铁路隧道工程安全工作的若干意见》中指出…...
15.2 矩阵链乘法
1.代码 public class MatrixChainMultiplication {public static void main(String[] args) { // 在该代码中,我们首先创建了两个n * n的矩阵m和s,分别用于记录最优值和分割点。 其中m 矩阵 通过i j 来显示在i到j的矩阵链中最优解 // // …...
向隐形冠军学习:聚焦人效,用时间管理提效益
注: 本文来源于盖雅工场联合创始人兼CEO 章新波 在2023狮山论坛“ 向隐形冠军学习: 聚焦人效,用时间管理提效益 ”的主题分享。 文|章新波 整理 |盖雅学苑 在人力资源行业以及各大企业,「人效」这个词…...
Protocol Buffers Go Generated Code Guide
Protocol Buffers Go 代码生成指南 本主题准确描述了协议缓冲区编译器为任何给定的协议定义生成的Go代码。 编译器调用 协议缓冲区编译器需要一个插件来生成Go 代码。使用Go 1.16或更高版本安装,方法是运行: go install google.golang.org/protobuf/…...
Python VTK STL 映射三维模型表面距离
目录 前言: 效果: 实现步骤: Code: 前言: 本文介绍了Python VTK映射三维模型表面距离,通过如何使用VTK计算两个三维模型(stl)的表面距离,并将其距离值以颜色映射到模型,可用于对比 两相模型…...
C# 异常处理机制和常见的异常类型
在 C# 中,异常处理是一个非常重要的概念,它可以让我们在程序发生错误时进行有效的处理,使程序具备更好的鲁棒性。C# 异常处理机制基于 try-catch-finally 语句块,其基本用法如下: try {// 可能会抛出异常的代码 } cat…...
【0187】客户端身份验证配置文件视图之pg_hba_file_rules
文章目录 1. 客户端身份验证配置文件视图2. 视图效果相关阅读: 【0179】配置PostgreSQL以允许远程连接 【0180】PG内核通过pg_hba.conf完成客户端认证(1) 【0181】PG内核通过pg_hba.conf完成客户端认证(2)...
模糊层次分析法(FAHP)Python实现
文章目录 理论基础三角模糊数概念参考 Python源码测试 理论基础 \quad 模糊层次分析法( F A H P FAHP FAHP)将模糊理论( F u z z y S e t Fuzzy Set FuzzySet)嵌入到基本层次分析法( A H P AHP AHP)中。 A …...
gdb切换窗口焦点
为了辅助调试,一般会使用layout src,调起TUI显示代码: 然而这种情况下我们写命令很不方便,无法方便地使用上一条命令、退格等。 按动上下左右方向键盘只会移动代码框,然而在伪终端下,可以用鼠标滚轮来上下…...
【Spring Security】 入门实战
文章目录 一、基本概念二、Spring Security第一个程序三、Spring Security没有生效四、修改默认账号密码(appliction.yml)五、修改默认账号密码(配置类)六、Spring Security的三个configure方法七、Spring Security的三种身份的验…...
SpringBoot的Interceptor拦截器的简介和实际使用
拦截器(Interceptor) 概念:是一种动态拦截方法调用的机制,类似于过滤器。Spring框架中提供的,用来动态拦截控制器方法的执行。 作用:拦截请求,在指定的方法调用前后,根据业务需要执行…...
5个面向Python高级开发者的技巧
使用这些用于自定义类行为、编写并发代码、管理资源、存储和操作数据以及优化代码性能的高级技术来探索 Python 的深度。 本文探讨了 Python 中的五个高级主题,它们可以为解决问题和提高代码的可靠性和性能提供有价值的见解和技术。从允许您在定义类时自定义类行为的…...
Nginx简介
Nginx是什么?可以做什么事情? Nginx是高性能的HTTP和反向代理的web服务器,处理高并发的能力十分强大,能经受高负载的考研,有报告表明能能支持高达50000个并发连接数。 特点 占有内存少:一万个长连接&…...
十五分钟带你学会 Electron
文章目录 什么是 Electron为什么要选择 Electron安装 Electron桌面CSDN实战Electron 基础配置Electron 进程主进程渲染进程主进程与渲染进程的区别主进程与渲染进程的通信 Electron 跨平台问题Electron 部署打包应用程序发布应用程序 Electron 跨端原理总结 什么是 Electron E…...
设计模式-结构型模式之桥接模式
2. 桥接模式 2.1. 模式动机 设想如果要绘制矩形、圆形、椭圆、正方形,我们至少需要4个形状类,但是如果绘制的图形需要具有不同的颜色,如红色、绿色、蓝色等,此时至少有如下两种设计方案: 第一种设计方案是为每一种形状…...
软件测试工程师为什么要写测试用例?
软件测试工程师为什么要写测试用例?相信从事软件测试行业的从业者来讲,测试用例并不陌生。因为测试用例不仅仅是一组简单的文档,它包含前提条件、输入、执行条件和预期结果等等重要内容,并且能够完成一定的测试目的和需求。下面本…...
【DAY40】VUE练习
DOS命令: DOS(Disk Operating System)是一种操作系统,它使用命令行界面(Command Prompt)进行交互。在 DOS 中,有一些常用的命令,可以用来定位目录、创建、删除、拷贝文件和目录&…...
实模式的寄存器
实模式的寄存器有8个通用寄存器,分别为AX、BX、CX、DX、SI、DI、BP和SP。通用的意思就是它们之中的大部分可以根据需要用于多种目的。 AX: accumulator,累加寄存器 BX: base,基址寄存器 CX: count,计数寄存器 SI: Source Index&am…...
【UE 控件蓝图】通过键盘选中要点击的按钮 通过Enter键点击
上一篇【UE 控件蓝图】菜单及功能实现博客已经完成了菜单的制作,但是我们只能通过鼠标来点击菜单选项,本篇博客实现的是能够通过键盘的上下键来选中按钮,然后按下“Enter”键来实现点击按钮的效果。 效果 可以看到并没有移动鼠标也可以通过…...
独立开发者如何借助Taotoken多模型能力打造全能AI助手应用
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 独立开发者如何借助Taotoken多模型能力打造全能AI助手应用 对于独立开发者或小型工作室而言,构建一个功能全面的AI助手…...
从零构建AOD-Net:PyTorch实战图像去雾模型开发全流程
1. 环境准备与数据理解 在开始构建AOD-Net之前,我们需要先搭建好开发环境。推荐使用Anaconda创建独立的Python环境,避免与其他项目产生依赖冲突。这里我选择Python 3.8和PyTorch 1.12的组合,这个版本经过实测在图像处理任务中表现稳定。 安装…...
【优化交叉口的绿灯时间】基于遗传算法的交通灯管理研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
构建动态技能图谱:从数据模型到自动化可视化的完整实践
1. 项目概述:一个技能图谱的诞生最近在GitHub上看到一个挺有意思的项目,叫dortort/skills。乍一看,这只是一个个人仓库,但点进去你会发现,它远不止是一个简单的代码集合。它更像是一张动态的、可视化的个人技能地图&am…...
Go语言实现跨平台系统更新检查器:自动化运维与安全监控实践
1. 项目概述:一个被低估的系统运维“哨兵”在服务器和桌面系统的日常运维中,有一个场景大家一定不陌生:某天,你管理的服务器突然因为一个已知漏洞被攻击,事后排查发现,相关的安全补丁其实在几周前就已经发布…...
LVGL在无显存TFT屏上的驱动适配:双缓冲与DMA优化实践
1. 项目概述:当TFT屏幕遇上LVGL最近在做一个嵌入式GUI项目,核心任务是把LVGL这个轻量级图形库,适配到一块分辨率不算高但接口比较“个性”的TFT屏幕上。这活儿听起来像是把标准插头插到非标插座上,得自己动手改改线序。LVGL这几年…...
从零到联网:QNX Neutrino RTOS安装后的第一个网络配置实战(含ifconfig与DHCP详解)
从零到联网:QNX Neutrino RTOS安装后的第一个网络配置实战 当你第一次看到QNX Neutrino RTOS的Photon桌面时,那种兴奋感可能很快会被一个现实问题冲淡——这个看起来酷炫的系统怎么连上网?作为实时操作系统领域的标杆,QNX在车载系…...
开源AI图像生成工具Dream-Creator:本地部署与Stable Diffusion实战指南
1. 项目概述:一个开源的AI图像生成与创作工具 最近在GitHub上闲逛,发现了一个挺有意思的项目叫“Dream-Creator”。光看名字,你可能会联想到一些AI绘画或者创意生成工具。没错,这确实是一个围绕AI图像生成的开源项目。作为一个在…...
Ash印相渲染失败率骤升47%?紧急预警:V6.2更新后Gamma 2.2→2.4迁移引发的印相断层危机
更多请点击: https://intelliparadigm.com 第一章:Ash印相渲染失败率骤升47%的全局现象与危机定性 近期,全球多个采用 Ash 印相引擎(v3.8.2)的影像处理平台集中报告渲染任务异常终止、输出空白或超时中断。监控数据显…...
DeepLake:AI原生数据湖统一管理多模态数据与向量嵌入
1. 项目概述:当数据湖遇上AI向量化如果你正在构建一个AI应用,无论是RAG检索增强生成系统、多模态模型训练,还是复杂的语义搜索,数据管理环节的复杂性往往会让你头疼不已。传统的文件系统、数据库,甚至是对象存储&#…...
