C++ 双端队列(deque)的深入理解

news2024/11/24 0:58:48

前言:

双端队列deque看起来是一个相当牛的容器,表面看起来将list和vector进行结合起来,形成了一个看起来很完美的容器,但是事实不是这样,要是deque如此完美,数据结构也就没list和vector的事情了,数据结构早就重新洗牌了,接下来我们一起探究一下deque的奥妙

内容摘要:

本文通过 双端队列的介绍、双端队列的内部结构、迭代器机理、缺陷这几个方面进行了介绍;分析了双端队列的底层实现结构,并通过和vector、list进行对比分析,希望能够给大家带来收获。

list和vector的优缺点分析

先将vector容器和list容器的优缺点进行分析,方便后续将双端队列的底层进行分析。

对于list来说:优点是  插入删除效率高:list由一个一个节点组成,在进行插入和删除数据时只需要进挪动指针,并不需要挪动数据 。不过缺点也比较明显:只能通过指针的遍历进行元素数据的访问,不能过进行任意位置的数据访问,任意位置访问的效率相对于vector效率较低;

对于vector来说:优点是①可以进行任意位置的数据访问:在内存中空间是连续的可以通过下标进行任意位置数据的访问   ②CPU高速缓存效率高,因为CPU可以利用预取技术提前加载相邻的元素、缓存行(通常为64字节)会一次性加载一段连续的内存。缺点是①vector需要进行扩容操作,扩容操作也就意味着开辟更大的空间,有可能会造成空间的浪费。②由于vector本身结构的问题,当进行插入和删除数据时,需要进行数据的挪动,尤其是当进行头插操作时,会将容器中所有的数据都进行挪动,这是很要命的

双端队列的介绍

双端队列是一种能够进行头插、尾插、头删、尾删、任意位置插入、任意位置进行删除并且还能够进行任意位置进行遍历的队列,这里需要注意deque并不是包含在queue头文件下的,要想进行deque的使用需要包含#include<deque>。

双端队列的内部结构

双端队列即能够进行头插、尾插、头删、尾删、任意位置插入、任意位置进行删除并且还能够进行任意位置进行遍历,这是怎么做到的呢???接下来让我们来看一下双端队列的结构

注意:这里每一个数组指针进行开辟的空间大小都是相同的

双端队列deque通过创建一个指针数组,刚开始存储的指针位于数组的中间位置,中间位置也被称为中控,当想要进行头插操作时,在指针数组的中间往前的插入一个指针,通过指针进行开辟一片空间,然后在这片空间在进行如图所示的插入操作,这样就巧妙的进行了插入操作;尾插也是通过同样的技巧进行的,如果指针数组中最后一个数组指针指向的空间没有满,则在这个数组指针指向的数组的空位置进行插入,如果存放的最后一个数组指针指向的数组已满则通过指针进行开辟一片空间然后进行插入操作。

当想要进行在中间任意位置进行插入操作时,这里就有两种思路,

其一是通过数组指针进行扩容操作,然后在进行指定位位置的插入,这样的好处在于,每次进行中间任意指定位置的插入,不需要进行挪动指定位置后的全部数据,只需要挪动一个数组指针指向的数组中的一小部分数据,插入效率对于list来说还是弱势一些毕竟需要进行数据的挪动,但是相对于vector高了许多相,但是这种方式牺牲了任意位置进行访问数据的优势

其二,当需要进行中间任意位置的插入操作时,每个数组指针刚开始开辟的空间大小是不变的,通过将在指定位置以及指定位置以后的元素进行向后挪动,确保每个数组指针指向的空间位置大小是相同的,这种做法是牺牲了中间位置的插入效率来确保遍历访问的效率。SGI版本就是使用的这种确保住访问遍历效率的方式。

当进行任意的位置访问时,例如想要进行位置位置数据元素的获取时((n-3)/10)%10就能够找到n位置的元素

deque中的迭代器维护结构的机理

deque中的迭代器是通过四个指针进行实现的,cur指针是指向当前元素的位置,first是指向小数组首元素的位置,last是指向小数组最后末位元素的位置,而node指针指向指针数组中指针的位置,当迭代器通过封装这四个指针实现的迭代器。当cur在last指针之前,当迭代器指针进行++时,cur向后移动一个位置;当cur指针和last指针指向同一片位置,当迭代器指针在进行++时,node指针就需要向后移动一个位置,找到下一个小数组的位置,然后在进行更新cur、first、last的位置。

deque的缺陷

deque最大的缺陷就是不够极致

与vector比较,deque的优势是:头部插入和删除时,不需要搬移元素,效率特别高,而且在扩容时,也不 需要搬移大量的元素,因此其效率是必vector高的。 与list比较,其底层是连续空间,空间利用率比较高,不需要存储额外字段。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2186090.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

多系统萎缩患者必看!这些维生素助你对抗病魔

亲爱的朋友们&#xff0c;今天我们来聊聊一个相对陌生但重要的健康话题——多系统萎缩&#xff08;MSA&#xff09;。这是一种罕见的神经系统疾病&#xff0c;影响着患者的自主神经系统、运动系统和平衡功能。面对这样的挑战&#xff0c;科学合理的饮食和营养补充显得尤为重要。…

暴力数据结构——AVL树

1.认识AVL树 AVL树最先发明的⾃平衡⼆叉查找树,AVL可以是⼀颗空树,或者具备下列性质的⼆叉搜索树&#xff1a; • 它的左右⼦树都是AV树&#xff0c;且左右⼦树的⾼度差的绝对值不超过1 • AVL树是⼀颗⾼度平衡搜索⼆叉树&#xff0c; 通过控制⾼度差去控制平衡 AVL树整体结点…

路由交换实验指南

案例 01&#xff1a;部署使用 eNSP 平台实验需求&#xff1a; 安装华为 eNSP 网络模拟平台打开 eNSP 平台&#xff0c;新建拓扑并绘制网络能够成功启动交换机、计算机设备 实验步骤&#xff1a; 安装华为 eNSP 网络模拟平台启动安装程序 配置安装内容 防护墙允许 eNSP 程序的…

IDTL:茶叶病害识别数据集(猫脸码客 第205期)

Identifying Disease in Tea Leaves茶叶病害识别数据集 一、引言 在农业领域&#xff0c;茶叶作为一种重要的经济作物&#xff0c;其生产过程中的病害防治是确保茶叶质量和产量的关键环节。然而&#xff0c;传统的病害识别方法主要依赖于人工观察和经验判断&#xff0c;这不仅…

从零开始实现RPC框架---------项目介绍及环境准备

一&#xff0c;介绍 RPC&#xff08;Remote Procedure Call&#xff09;远程过程调⽤&#xff0c;是⼀种通过⽹络从远程计算机上请求服务&#xff0c;⽽不需要 了解底层⽹络通信细节。RPC可以使⽤多种⽹络协议进⾏通信&#xff0c; 如HTTP、TCP、UDP等&#xff0c; 并且在 TCP/…

匿名方法与Lambda表达式+泛型委托

匿名方法 和委托搭配使用&#xff0c;方便我们快速对委托进行传参&#xff0c;不需要我们定义一个新的函数&#xff0c;直接用delegate关键字代替方法名&#xff0c;后面跟上参数列表与方法体。 格式&#xff1a;delegate(参数列表){方法体} lambda表达式 是匿名方法的升级…

Brave编译指南2024 MacOS篇-环境配置(四)

引言 在上一篇文章中&#xff0c;我们成功获取了Brave浏览器的源代码。现在&#xff0c;我们将进入编译过程的关键阶段&#xff1a;环境配置。正确的环境配置对于成功编译Brave浏览器至关重要&#xff0c;它能确保所有必要的工具和依赖项都已就位&#xff0c;并且版本兼容。 …

JAVAIDEA初始工程的创建

四结构 建工程综述* 初始*&#xff1a; 1、先建个空项目&#xff0c; 2、打开文件中的项目结构新建module模块&#xff08;模块下有src&#xff09; 修改模块名&#xff1a; 也是Refactor&#xff0c;Rename&#xff0c;但是要选第三个同时改模块和文件夹名字 导入模块&am…

【Python】ftfy 使用指南:修复 Unicode 编码问题

ftfy&#xff08;fixes text for you&#xff09;是一个专为修复各种文本编码错误而设计的 Python 工具。它的主要目标是将损坏的 Unicode 文本恢复为正确的 Unicode 格式。ftfy 并非用于处理非 Unicode 编码&#xff0c;而是旨在修复因为编码不一致、解码错误或混合编码导致的…

【Python】path:简化文件路径处理的 Python 库

path 是一个 Python 库&#xff0c;提供了对文件系统路径的简洁抽象&#xff0c;使文件和目录操作更加直观和 Pythonic。该库建立在 pathlib 的基础上&#xff0c;扩展了文件路径处理的功能&#xff0c;使得开发者能够更高效地进行文件操作&#xff0c;如文件读写、目录遍历、路…

Redis缓存穿透雪崩击穿及解决

封装缓存空对象解决缓存穿透与逻辑过期解决缓存击穿工具类 Slf4j Component public class CacheClient {private final StringRedisTemplate stringRedisTemplate;public CacheClient(StringRedisTemplate stringRedisTemplate) {this.stringRedisTemplate stringRedisTemplat…

《Linux从小白到高手》理论篇(十一):Linux的系统环境管理

值此国庆佳节&#xff0c;深宅家中&#xff0c;闲来无事&#xff0c;就多写几篇博文。本篇详细深入介绍Linux的系统环境管理。 环境变量 linux系统下&#xff0c;如果你下载并安装了应用程序&#xff0c;很有可能在键入它的名称时出现“command not found”的提示内容。如果每…

震撼!AI造声新标杆,20字生成完美音频

震撼&#xff01;AI造声新标杆&#xff0c;20字生成完美音频 EzAudio是一款革命性的文本到音频生成AI&#x1f3b6;&#xff0c;快速生成高质量音频&#xff0c;告别机械音&#x1f50a;。它能将文字瞬间变成音乐和配音&#xff0c;为创作增添无限可能✨&#xff01;快来体验这…

源2.0全面适配百度PaddleNLP,大模型开发开箱即用

近日&#xff0c;源2.0开源大模型与百度PaddleNLP完成全面适配。用户通过PaddleNLP&#xff0c;可快速调用源2.0预训练大模型&#xff0c;使用源2.0在语义、数学、推理、代码、知识等方面的推理能力&#xff0c;也可以使用特定领域的数据集对源2.0 进行微调&#xff0c;训练出适…

C++11_lambda

lambda表达式 在C98中&#xff0c;如果想要对一个数据集合中的元素进行排序&#xff0c;可以使用std::sort方法。比如说&#xff0c;我想在某宝买一件商品&#xff0c;我想买该商品价格最便宜的哪一个&#xff0c;这就需要对价格排升序&#xff1b;我如果想买性价比最高的&…

AAC-Fe³⁺水凝胶,兼具拉伸性与导电性,还有自修复和4D打印能力

大家好&#xff01;今天我们来了解一种用于可拉伸电子产品的创新材料——自修复和4D打印水凝胶——《Self‐Healable and 4D Printable Hydrogel for Stretchable Electronics》发表于《Advanced Science》。在科技发展中&#xff0c;可拉伸电子产品需求大增&#xff0c;但现有…

我尝试了LangGraph Studio的AI Agent功能

构建一个真正“智能”的Agent——一个能够理解语言、做出决策并进行有意义互动的Agent——并不像编写几行代码那么简单。 它需要对AI原理和软件工程有深刻的理解。 此外&#xff0c;传统的软件工具并不适合Agent的开发&#xff0c;无法满足其独特需求。 这也是像LangGraph S…

【数据分享】2001-2023年我国省市县镇四级的逐月平均气温数据(免费获取/Shp/Excel格式)

之前我们分享过1901-2023年1km分辨率逐月平均气温栅格数据&#xff0c;该数据来源于国家青藏高原科学数据中心。为方便大家使用&#xff0c;我们还基于上述平均气温栅格数据将数据处理为Shp和Excel格式的省市县三级逐月平均气温数据&#xff08;可查看之前的文章获悉详情&#…

10.2今日错题解析(软考)

目录 前言面向对象技术——设计模式的应用场景系统开发基础——概要设计与详细设计 前言 这是用来记录我备考软考设计师的错题的&#xff0c;今天知识点为设计模式的应用场景、概要设计与详细设计&#xff0c;大部分错题摘自希赛中的题目&#xff0c;但相关解析是原创&#xf…

银河麒麟V10如何配置外网yum源?

银河麒麟V10如何配置外网yum源&#xff1f; 一、常用的软件源地址二、配置yum源的步骤1. 打开终端2. 进入yum配置文件目录3. 编辑或创建.repo文件4. 配置软件源信息5. 保存并退出6. 更新软件包列表7. 验证软件源 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不…