C++STL——deque容器详解

纵有疾风起,人生不言弃。本文篇幅较长,如有错误请不吝赐教,感谢支持。
💬文章目录
- 一.deque容器的基本概念
- 二.deque容器常用操作
- ①deque构造函数
- ②deque元素操作
- ③deque赋值操作
- ④deque交换操作
- ⑤deque大小操作
- ⑥deque插入和删除
一.deque容器的基本概念
vector容器是单向开口的连续内存空间,deque(['dek])则是一种双向开口的连续线性空间。所谓的双向开口,意思是可以在头尾两端分别做元素的插入和删除操作,可以理解为数据结构的双端队列。当然,vector容器也可以在头尾两端插入元素,但是在其头部操作效率奇差,全部元素都要后移,无法被接受。

✅deque容器和vector容器的差异:
- ①deque是双端队列,可在容器的头部和尾部插入或删除元素。
- ②deque没有容量的概念,因为它是动态的以分段连续空间组合而成,随时可以增加一段新的空间并链接起来,换句话说,deque不会像vector那样,”旧空间不足而重新配置一块更大空间,然后复制元素,再释放旧空间”这样的事情在deque身上是不会发生的。deque可以随时将空间串接在首部或尾部,也因此,deque没有必须要提供所谓的空间保留(reserve)功能。
✅deque容器内部实现原理:
deque容器在逻辑上是一片连续的空间,但这只是一种假象,实际deque是由一段一段的定量的连续空间构成。一旦有必要在deque前端或者尾端增加新的空间,便配置一段连续定量的空间,串接在deque的头端或者尾端。deque最大的工作就是维护这些分段连续的内存空间的整体性的假象,并提供随机存取的接口,避开了(1)重新配置空间申请更大空间 (2)原数据复制新空间 (3)释放原空间三步骤,代价就是复杂的迭代器架构。
既然deque是分段连续内存空间,那么就必须有中央控制,维持整体连续的假象。deque内部存在中央控制器,记录与维护每段数据缓冲区(存储数据的空间)的内存地址,缓冲区中存储真实数据,保证可从容器的头部与尾部插入或删除元素。缓冲区才是deque的存储空间主体。

deque容器的迭代器:
支持随机访问的迭代器,可跳跃式访问容器元素。
二.deque容器常用操作
①deque构造函数
作用:创建deque容器。
注:使用deque容器时,需包含头文件#include <deque>
| 函数原型 | 解释 |
|---|---|
deque<T> deq T; | 默认构造形式(显示实例化) |
| deque(beg, end); | 构造函数将[beg, end)区间中的元素拷贝给本身。 |
| deque(n, elem); | 有参构造函数,使用n个elem元素进行初始化。 |
| deque(const deque &deq); | 拷贝构造函数,使用已有deque对象初始化新的对象。 |
实例:deque构造函数
#include <iostream>
using namespace std;
#include <deque>//包含头文件
void printdeque(const deque<int>& deq)//形参使用const,避免被修改
{ //const_iterator只读迭代器for (deque<int>::const_iterator it = deq.begin(); it != deq.end(); ++it){cout << *it<<"|";}cout << endl;
}
void test()
{deque<int> v1 = { 1,2,3 };//采用模板实现类实现(显示实例化),默认构造函数,deque<int> v2(6, 1);//构造函数将n个elem拷贝给本身。int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };deque<int> v3(arr, arr + sizeof(arr) / sizeof(arr[0]));//将v[begin(), end())区间中的元素拷贝给本身deque<int> v4(v1);//拷贝构造函数,拿另一个vector对象初始化本身printdeque(v1);printdeque(v2);printdeque(v3);printdeque(v4);
}
int main()
{test();return 0;
}

②deque元素操作
作用:通过重载赋值运算符operator[]和成员函数at(int index),对deque容器的单个元素进行读(作为右值)或写(作为左值)。
| 函数原型 | 解释 |
|---|---|
| T &operator[](size_t n); | 通过[]访问元素,如果越界,不抛异常,程序直接挂掉 |
| T &at(size_t n); | 通过at方法获取下标为n的元素,如果n越界,抛出out_of_range异常。 |
| T *data(); | 返回容器中动态数组的首地址。 |
| const T *data() const; | 返回容器中动态数组的首地址。 |
| T &front(); | 返回第一个元素。 |
| T &back(); | 返回,最后一个元素。 |
③deque赋值操作
作用:通过重载赋值运算符operator=和成员函数assign(),对deque容器进行赋值。
| 函数原型 | 解释 |
|---|---|
| assign(beg, end); | 拷贝目标deque容器中[begin(), end())区间的元素,对当前deque容器赋值。 |
| assign(n, elem); | 将n个elem拷贝赋值给本身。 |
| deque&operator=(const deque &deq); | 重载等号操作符 |
| swap(deq); | 将deq与本身的元素互换 |
实例:deque赋值操作
#include <iostream>
using namespace std;
#include <deque>//包含头文件
void printdeque(const deque<int>& deq)//形参使用const,避免被修改
{ //const_iterator只读迭代器for (deque<int>::const_iterator it = deq.begin(); it != deq.end(); ++it){cout << *it<<"|";}cout << endl;
}
void test()
{deque<int> deq;//尾插法插入元素for (int i = 0; i < 5; i++) {deq.push_back(i);}//遍历printdeque(deq); //0 1 2 3 4/* 1.重载运算符=赋值 */deque<int> d1;d1 = deq;printdeque(d1); //0 1 2 3 4/* 2.assign()函数,区间拷贝 */deque<int> d2;d2.assign(deq.begin(), deq.end());printdeque(d2); //0 1 2 3 4/* 3.assign()函数,n个elem元素赋值 */deque<int> d3;//5个整型元素6d3.assign(5, 6);printdeque(d3); //6 6 6 6 6
}
int main()
{test();return 0;
}

④deque交换操作
💬表格一览:
| 函数原型 | 解释 |
|---|---|
| void swap(deque &deq); | 把当前容器与deq交换。 |
实例:deque交换操作
#include <iostream>
using namespace std;
#include <deque>//包含头文件
void printdeque(const deque<int>& deq)//形参使用const,避免被修改
{ //const_iterator只读迭代器for (deque<int>::const_iterator it = deq.begin(); it != deq.end(); ++it){cout << *it<<"|";}cout << endl;
}
void test()
{deque<int> deq;//尾插法插入元素for (int i = 0; i < 5; i++) {deq.push_back(i);}//遍历printdeque(deq); //0 1 2 3 4deque<int> d1;d1.swap(deq);//将deq与本身的元素互换printdeque(d1);
}
int main()
{test();return 0;
}

⑤deque大小操作
作用:操作deque容器的大小(即元素个数)。
| 函数原型 | 解释 |
|---|---|
| bool empty() const; | 判断容器是否为空。 |
| size_t size() const; | 返回容器的实际大小(已使用的空间)。 |
| resize(int num); | 重新指定容器的长度为num。若容器变长,则以默认值0填充新位置;若容器变短,则容器末尾超出新长度的元素被删除。 |
| resize(int num, elem); | 重新指定容器的长度为num。若容器变长,则以指定值elem填充新位置;若容器变短,则容器末尾超出新长度的元素被删除。 |
实例:deque大小操作
#include <iostream>
using namespace std;
#include <deque>//包含头文件
void printdeque(const deque<int>& deq)//形参使用const,避免被修改
{ //const_iterator只读迭代器for (deque<int>::const_iterator it = deq.begin(); it != deq.end(); ++it){cout << *it<<"|";}cout << endl;
}
void test()
{deque<int> deq;//尾插法插入元素for (int i = 0; i < 5; i++) {deq.push_back(i);}printdeque(deq); //0 1 2 3 4//empty():判断容器是否为空cout << (deq.empty() ? "deq为空" : "deq不为空") << endl; //deq不为空//size(); :获取容器的大小,即元素个数。cout << "deq的大小/元素个数:" << deq.size() << endl; //5//resize(int num);:重新指定容器的长度为num//若容器变长,则以默认值0填充新位置;若容器变短,则容器末尾超出新长度的元素被删除。deq.resize(10); //长度变大时,使用默认值0填充printdeque(deq); //0 1 2 3 4 0 0 0 0 0deq.resize(3); //长度变小时,容器末尾超出新长度的元素被删除printdeque(deq); //0 1 2//resize(int num, elem); :重新指定容器的长度为num。//若容器变长,则以指定值elem填充新位置;若容器变短,则容器末尾超出新长度的元素被删除。deq.resize(8, 6); //长度变大时,使用指定值6填充printdeque(deq); //0 1 2 6 6 6 6 6}
int main()
{test();return 0;
}

注:deque容器不存在容量的概念,即不存在capacity()成员函数。可随时开辟缓冲区存储数据。
⑥deque插入和删除
💬表格一览:
| 函数原型 | 解释 |
|---|---|
| iterator insert(iterator pos, const T& ele); | 在指定位置插入一个元素ele 返回指向插入元素的迭代器。 |
| iterator insert(const_iterator pos, int count,ele); | 迭代器指向位置pos插入count个元素ele.返回指向插入元素的迭代器。 |
| void push_front(const T& ele); | 在容器头部插入一个数据 |
| void push_back(const T& ele); | 尾部插入元素ele |
| void pop_front(); | 删除容器第一个数据 |
| void pop_back(); | 删除最后一个元素 |
| void clear(); | 清空容器。 |
| iterator erase(const_iterator start, const_iterator end); | 删除迭代器从start到end之间的元素,返回下一个有效的迭代器。 |
| iterator erase(const_iterator pos); | 删除迭代器指向的元素,返回下一个有效的迭代器。 |
实例:deque插入和删除
#include <iostream>
using namespace std;
#include <deque>//包含头文件
void printdeque(const deque<int>& deq)//形参使用const,避免被修改
{ //const_iterator只读迭代器for (deque<int>::const_iterator it = deq.begin(); it != deq.end(); ++it){cout << *it<<"|";}cout << endl;
}
void test()
{deque<int> v;for (int i = 0; i < 5; i++){v.push_back(i + 1);//尾部插入元素}printdeque(v);//1 2 3 4 5v.insert(v.begin() + 1, 2, 100);//在第二个元素插入2个100printdeque(v);//1 100 100 2 3 4 5v.pop_front();//头部删除一个元素v.pop_back();//尾部删除一个元素printdeque(v);//100 100 2 3 4cout << "-------------" << endl;v.erase(v.begin());//删除第一个元素printdeque(v);//100 2 3 4deque<int>::const_iterator it = v.erase(v.begin() + 1, v.end() - 1);//删除从第二个元素到倒数第二个元素,返回下一个有效迭代器printdeque(v);//100 4v.insert(it, 66);printdeque(v);//100 66 4v.clear();//清空容器
}
int main()
{test();return 0;
}

相关文章:
C++STL——deque容器详解
纵有疾风起,人生不言弃。本文篇幅较长,如有错误请不吝赐教,感谢支持。 💬文章目录 一.deque容器的基本概念二.deque容器常用操作①deque构造函数②deque元素操作③deque赋值操作④deque交换操作⑤deque大小操作⑥deque插入和删除…...
docker 哨兵模式和集群模式安装Redis7.0.12
docker 哨兵模式和集群模式安装Redis7.0.12 1.下载镜像 1.1 配置阿里云加速源 墙外能访问https://hub.docker.com/_/redis 的可跳过 https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors 登录后选择左侧的镜像工具>镜像加速器,获取加速器地址&#…...
go nil 与零值
go nil 与零值 区别描述: 在Go语言中,nil和零值是两个不同的概念,它们在处理空值或未初始化值时有不同的应用场景。 nil: 在Go语言中,nil表示指针类型的零值或者interface、function、map、slice、channel、error类…...
puppeteer监听response并封装为express服务调用
const express require(express); const puppeteer require(puppeteer); const app express(); let browser; // 声明一个全局变量来存储浏览器实例app.get(/getInfo, async (req, res) > {try {const page_param req.query.page; // 获取名为"page"的查询参数…...
kubernetes之Ingress
一、背景 Ingress是k8s中实现7层负载的实现方式,是公开集群外部流量到集群内服务的HTTP和HTTPS路由 二、Ingress基础 通常Ingress实现由Ingress 控制器和Ingress组成,Ingress控制器负责具体实现反向代理及负载均衡,Ingress负责定义匹配规则和…...
前端实现打印1 - 使用 iframe 实现 并 分页打印
目录 打印代码对话框预览打印预览 打印代码 <!-- 打印 --> <template><el-dialogtitle"打印":visible.sync"dialogVisible"width"50%"top"7vh"append-to-bodyclose"handleClose"><div ref"print…...
MIAOYUN获评“2023年度一云多芯稳定安全运行优秀案例”
2023年7月25日至26日,由中国信息通信研究院(简称“中国信通院”)、中国通信标准化协会主办的以“云领创新,算启新篇”为主题的“2023可信云大会”在北京成功举办。会上公布了多项前瞻领域的评估结果和2023年度最佳实践案例&#x…...
论文代码学习—HiFi-GAN(4)——模型训练函数train文件具体解析
文章目录 引言正文模型训练代码整体训练过程具体训练细节具体运行流程 多GPU编程main函数(通用代码)完整代码 总结引用 引言 这里翻译了HiFi-GAN这篇论文的具体内容,具体链接。这篇文章还是学到了很多东西,从整体上说,…...
安防视频综合管理合平台EasyCVR可支持的视频播放协议有哪些?
EasyDarwin开源流媒体视频EasyCVR安防监控平台可提供视频监控直播、云端录像、云存储、录像检索与回看、智能告警、平台级联、云台控制、语音对讲、智能分析等能力。 视频监控综合管理平台EasyCVR具备视频融合能力,平台基于云边端一体化架构,具有强大的…...
一张表格讲明白white-space属性。html如何识别\n\r,让这些特殊换行符换行。
大多数标签在展示文本内容的时候都会默认把文本中的空白和换行符去掉,这的确大大的使得文本的排版更加美观了,也怎加了区域的利用率,可是就有一些需求是需要原原本本的展示出原汁原味的文本格式。那该如何展示出文本的内在格式呢?…...
【Linux】编写shell脚本将项目前一天打印的日志进行提取,并且单独保存
业务场景:又到了熟悉的业务场景环节,其实应用上有很多,我们为了方便提取日志中部分关键的内容,对接给其他人也好,方便自己统计也罢,都会比每次我们都去服务器上及时查看,或者下载全部日志再筛选…...
快速搭建单机RocketMQ服务(开发环境)
一、什么是RocketMQ RocketMQ是阿里巴巴开源的一个消息中间件,在阿里内部历经了双十一等很多高并发场景的考验,能够处理亿万级别的消息。2016年开源后捐赠给Apache,现在是Apache的一个顶级项目。 早期阿里使用ActiveMQ,…...
Centos7搭建Apache Storm 集群运行环境
文章目录 1. 安装 Java2. 下载并解压 Storm3. 配置环境变量4. 配置 ZooKeeper5. 配置 Stormstorm.yaml自定义 storm.yamlstorm-env.shlogback/cluster.xml 6. 启动 Storm 集群7. 验证 1. 安装 Java Storm 运行在 Java 平台上,因此需要先安装 Java。你可以使用以下命…...
C语言假期作业 DAY 12
一、选择题 1、请阅读以下程序,其运行结果是( ) int main() { char cA; if(0<c<9) printf("YES"); else printf("NO"); return 0; } A: YES B: NO C: YESNO D: 语句错误 答案解析 正确答案: A 0<c&l…...
2.4在运行时选择线程数量
在运行时选择线程数量 C标准库中对此有所帮助的特性是std::thread::hardware_currency()。这个函数返回一个对于给定程序执行时能够真正并发运行的线程数量的指示。例如,在多核系统上它可能是CPU 核心的数量。它仅仅是一个提示,如果该信息不可用则函数可…...
element-ui中Notification 通知自定义样式、按钮及点击事件
Notification 通知用于悬浮出现在页面角落,显示全局的通知提醒消息。 一、自定义html页面 element-ui官方文档中说明Notification 通知组件的message 属性支持传入 HTML 片段,但是示例只展示了简单的html片段,通常不能满足开发中的更深入需要…...
无头单向非循环单链表、带头双向循环链表
文章内容 1. 链表的概念及结构 2. 链表的分类 3.链表实现 4.代码 文章目录 1. 链表的概念及结构 概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表 中的指针链接次序实现的 。 现实中 数据结构中 链表和顺序表…...
UE4/5C++多线程插件制作(二十、源码)
目录 头文件 MultiThreadPlugins.uplugin MultiThreadPlugins.Build.cs MultiThreadPlugins.h MTPPlatform.h MTPManage.h RTPAgendy.h MTPThreadTaskManage.h...
构建稳健的PostgreSQL数据库:备份、恢复与灾难恢复策略
在当今数字化时代,数据成为企业最宝贵的资产之一。而数据库是存储、管理和保护这些数据的核心。PostgreSQL,作为一个强大的开源关系型数据库管理系统,被广泛用于各种企业和应用场景。然而,即使使用了最强大的数据库系统࿰…...
查看本地mysql账号密码
使用Navicat工具打开本地mysql,新建查询输入下面查询语句 SELECT user, authentication_string FROM mysql.user WHERE userroot将authentication_string 中的加密密码复制出来打开链接: Magic Data 5输入加密的密码,和验证码,点…...
RexUniNLU异常检测能力:识别虚假评论与垃圾内容
RexUniNLU异常检测能力:识别虚假评论与垃圾内容 1. 效果惊艳开场 打开任何一个内容平台,评论区总是最热闹的地方。但你可能不知道,每10条评论里,就有2-3条是机器生成的广告、水军刷的好评,或者是纯粹的垃圾信息。这些…...
如何快速掌握Mermaid在线编辑器:面向初学者的完整可视化工具指南
如何快速掌握Mermaid在线编辑器:面向初学者的完整可视化工具指南 【免费下载链接】mermaid-live-editor Edit, preview and share mermaid charts/diagrams. New implementation of the live editor. 项目地址: https://gitcode.com/GitHub_Trending/me/mermaid-l…...
AI动画创作新范式:Krita插件驱动的动态视觉叙事解决方案
AI动画创作新范式:Krita插件驱动的动态视觉叙事解决方案 【免费下载链接】krita-ai-diffusion Streamlined interface for generating images with AI in Krita. Inpaint and outpaint with optional text prompt, no tweaking required. 项目地址: https://gitco…...
别再死记硬背了!用Python可视化理解L-smooth函数与梯度Lipschitz连续
别再死记硬背了!用Python可视化理解L-smooth函数与梯度Lipschitz连续 第一次接触L-smooth这个概念时,我盯着数学公式看了整整一个下午——梯度Lipschitz连续、二次上界、等价性证明,每个词都认识,连起来却像天书。直到我用Python画…...
告别卡顿!用MobileNetv2+MPPTSNet-EC在树莓派上跑实时语义分割(附完整配置与性能测试)
树莓派实战:MobileNetv2MPPTSNet-EC实时语义分割全流程解析 当你在树莓派上第一次看到摄像头画面被实时分割成不同语义区域时,那种成就感绝对值得记录。本文将带你完整实现从模型选择到部署优化的全流程,用MobileNetv2MPPTSNet-EC这套组合拳&…...
mxbai-embed-large-v1 应用开发:从零构建智能文档检索系统
mxbai-embed-large-v1 应用开发:从零构建智能文档检索系统 1. 项目概述与核心价值 mxbai-embed-large-v1 是由 mixedbread-ai 开发的高性能文本嵌入模型,在 MTEB 基准测试中超越了 OpenAI text-embedding-3-large 等商业模型。该模型能够将文本转换为高…...
TextGrad部署与性能优化:生产环境最佳实践
TextGrad部署与性能优化:生产环境最佳实践 【免费下载链接】textgrad Automatic Differentiation via Text -- using large language models to backpropagate textual gradients. 项目地址: https://gitcode.com/gh_mirrors/te/textgrad TextGrad是一款基于…...
Kangaroo运动控制器Packet Serial通信协议详解
1. Kangaroo运动控制器底层通信技术解析 Kangaroo运动控制器是由RoboClaw系列厂商推出的专用闭环步进/伺服电机驱动模块,其核心价值在于将复杂的PID调节、电流环控制、位置反馈处理等算法固化于硬件中,使上位机仅需通过精简的串行协议即可完成高精度运动…...
创新音乐体验:foobox-cn全攻略
创新音乐体验:foobox-cn全攻略 【免费下载链接】foobox-cn DUI 配置 for foobar2000 项目地址: https://gitcode.com/GitHub_Trending/fo/foobox-cn 在数字音乐时代,如何将本地播放器与网络电台无缝融合,打造个性化的音乐中心…...
**NPU设计新范式:基于RISC-V的可配置计算单元实现与性能优化实践**在人工智能加速领域,
NPU设计新范式:基于RISC-V的可配置计算单元实现与性能优化实践 在人工智能加速领域,NPU(神经网络处理单元) 正从专用硬件向灵活可编程架构演进。本文将深入探讨一种基于 RISC-V指令集扩展 的轻量级NPU设计方案,并通过实…...
