c++的STL(3)-- deque容器

news/2024/5/30 18:49:43/文章来源:https://blog.csdn.net/weixin_68026222/article/details/136589166

目录

deque概述 

deque的内存模型 

注意: 

1. deque的默认构造(和vector类似)

 代码:

2. deque的有参构造(和vector类似)

 代码:

3. deque容器在首部和尾部添加或者元素

代码:

 相关知识点: 

4. deque容器的元素个数 (和vector类似)

 代码:

5.  deque在指定位置插入元素(和vector类似)

代码: 

相关知识点: 

6.deque容器元素的访问(和vector类似)

 代码:

7.  deque的迭代器(和vector使用方法是一样的)

8. deque容器删除元素(和vector类似) 

代码: 

相关知识点: 

 9.deque容器赋值(和vector类似)

代码: 

10.resize()修改元素个数(和vector中的类似)

11. deque()中的其它函数(和vector类似)

12. deque相对于vector函数的变动 

13. deque容器的注意事项 


 deque容器和vector容器的很多方法的使用都是类似的,如果一样就不在详述,请查看c++的STL(2)-- vector容器中的对应部分进行查看。

 如果要查看动态开辟空间内容以及注意事项,如何避免其带来的低效率。 以及reserve()和shrink_to_fit()函数的使用,请直接看vector容器中相关的内容。

deque概述 

  • deque是一个双端队列,内部是使用数组进行实现的,其内部的空间和vector容器不同,其空间并不一定是连续的。
  • deque在开头和尾部添加元素都是非常快的,但是deque在中间插入元素是很慢的,因为需要进行元素移动。 
  • deque可以也可以进行随机存取。

deque的内存模型 

通过建立 map 数组,deque 容器申请的这些分段的连续空间就能实现“整体连续”的效果。换句话说,当 deque 容器需要在头部或尾部增加存储空间时,它会申请一段新的连续空间,同时在 map 数组的开头或结尾添加指向该空间的指针,由此该空间就串接到了 deque 容器的头部或尾部。

有读者可能会问,如果 map 数组满了怎么办?很简单,再申请一块更大的连续空间供 map 数组使用,将原有数据(很多指针)拷贝到新的 map 数组中,然后释放旧的空间。

注意: 

鉴于deque的内存方式 -- 也就是存储数据的内存是不连续的,所以我们不能对deque中的数据使用指针进行访问。 --  应该使用迭代器。(迭代器是容器内嵌的类,进行了处理)

例子:

int main(void) {deque<int> d1{1,2,3,4,5};d1.emplace_front(6);int* a = &d1[1];
/*++a;cout << "a=" << *a << endl;
*/--a;cout << "a=" << *a << endl;system("pause");return 0;
}

代码中我们使用初始化列表,在d1容器中存放了5个元素,然后使用emplace_back()在其前面插入一个数据6。

按照上面的内存模型,我们知道存储6的空间和存储1-5的空间不是连续的。我们取1的地址存放到指针a当中,对a++之后,打印a中的数据是2。但是如果进行a--,打印a中的数据会发现时一串非法数字。

这就是因为1前面的6和他们不存储在同一片内存并且不连续,当a--的时候访问的是存储1的前一个内存,但是这里存储的并不是6而是一个垃圾值。

但是你会发现我们对a++,就可以正确的访问,这是因为1-5的空间是连续的,对a++后面的空间存储的是2。虽然这样可以,但是还是不要使用指针直接访问deque中的元素,因为你无法确定从哪里开始内存就不连续了,会有风险。

表  deque 容器的成员函数
函数成员函数功能
begin()返回指向容器中第一个元素的迭代器。
end()返回指向容器最后一个元素所在位置后一个位置的迭代器,通常和 begin() 结合使用。
rbegin()返回指向最后一个元素的迭代器。
rend()返回指向第一个元素所在位置前一个位置的迭代器。
cbegin()和 begin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
cend()和 end() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
crbegin()和 rbegin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
crend()和 rend() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
size()返回实际元素个数。
max_size()返回容器所能容纳元素个数的最大值。这通常是一个很大的值,一般是 232-1,我们很少会用到这个函数。
resize()改变实际元素的个数。
empty()判断容器中是否有元素,若无元素,则返回 true;反之,返回 false。
shrink _to_fit()将内存减少到等于当前元素实际所使用的大小。
at()使用经过边界检查的索引访问元素。
front()返回第一个元素的引用。
back()返回最后一个元素的引用。
assign()用新元素替换原有内容。
push_back()在序列的尾部添加一个元素。
push_front()在序列的头部添加一个元素。
pop_back()移除容器尾部的元素。
pop_front()移除容器头部的元素。
insert()在指定的位置插入一个或多个元素。
erase()移除一个元素或一段元素。
clear()移出所有的元素,容器大小变为 0。
swap()交换两个容器的所有元素。
emplace()在指定的位置直接生成一个元素。
emplace_front()在容器头部生成一个元素。和 push_front() 的区别是,该函数直接在容器头部构造元素,省去了复制移动元素的过程。
emplace_back()在容器尾部生成一个元素。和 push_back() 的区别是,该函数直接在容器尾部构造元素,省去了复制移动元素的过程。

要想使用deque容器,需要导入头文件#include <deque> 

下面的知识点,如果和vector类似,那么只会给出代码,具体的知识点请看vector容器的那一节。

1. deque的默认构造(和vector类似)

 代码:

#include <iostream>
#include <stdlib.h>
#include <deque>using namespace std;class Student {};int main(void) {/*deque<int> d1;deque<float> d1;deque<Student> d1;deque<Student *> d1;deque<int *> d1;*/system("pause");return 0;
}

2. deque的有参构造(和vector类似)

 代码:

/*有参构造:方式一:  使用初始化列表  c++11之后支持deque<int> d1{ 1,2,3,4,5 };方式二:  初始化时指定元素个数deque<int> d1(10);  // 指定元素个数为10,并且只为默认值(此处为0)deque<int> d1(10,5);// 10个元素的值为5方式三:  使用指针(数组)int arr[] = { 1,2,3,4,5 };deque<int> d1(arr,arr+2); //  区间左闭右开,将arr数组的前两个元素放到d1中方式四:  使用其它deque的迭代器deque<int> d1{10,20,30,40,50};deque<int> d2(d1.begin(), d1.begin() + 2);  // 区间左闭右开,将d1容器的前两个元// 素放到d2中// 使用其它容器的迭代器vector<int> v1{ 1,2,3,4,5 };deque<int> d1(v1.begin(),v1.end());方式五:   调用拷贝构造函数deque<int> d1{10,20,30,40,50};deque<int> d2(d1);  // 将d1中的元素放到d2中
*/

3. deque容器在首部和尾部添加或者元素

在deque的首尾插入和删除元素都是很快的,在首部插入,它会再开辟一段空间来存放,所以也不需要移动元素。

代码:

/*deque<int> d1;1. 尾部添加:  push_back() , emplace_back();q1.push_back(1);q1.emplace_back(2);int a = 10;q1.push_back(a);q1.emplace_back(a);2. 尾部删除:  pop_back();q1.pop_back();3. 首部添加:  push_front() , emplace_front();q1.push_front(1);q1.emplace_front(2);int a = 10;q1.push_front(a);q1.emplace_front(a);4. 首部删除:  pop_front();q1.pop_front();添加元素时,在空间不够的时候,会开辟空间删除元素时不影响容器容量
*/
 相关知识点: 
  • push_front()和emplace_front()函数可以在deque容器的前面添加一个元素,而且很快。
  • pop_front()函数可以删除deque容器中最前面的元素。
  • 至于在尾部添加和删除元素和vector类似
  • emplace_front()好人push_front()的区别,请看vector中相关内容的讲解

4. deque容器的元素个数 (和vector类似)

 代码:

deque<int> q1{1,2,3,4,5};cout << "q1容器的元素个数:" << q1.size() << endl; // 输出5

5.  deque在指定位置插入元素(和vector类似)

代码: 

/*deque<int> d1;deque在指定位置插入元素:方式一:  使用insert()1. d1.insert(d1.begin(), 5);  在开始位置插入52. d1.insert(d1.begin(), 5,3); 在开始位置插入5个33. d1.insert(d1.begin(), {1,2,3,4,5}); 在开始位置插入列表中的数据4. deque<int> d2{ 1,2,3,4,5 };d1.insert(d1.begin(), d2.begin()+1,d2.begin()+3); 在开始的位置插入[d2.begin()+1,d2.begin()+3)范围内的数据,范围为左闭右开vector<int> v1{ 1,2,3,4,5 };deque<int> d1;d1.insert(d1.begin(), v1.begin(), v1.end()); // 将v1中的元素插入到d1的开始位置5. int arr[] = { 1,2,3,5,4 };d1.insert(d1.begin(), arr+1,arr+3); 在开始位置插入指针[arr+1,arr+3)范围(左闭右开)内的数据。(也就是数组中的第二个元素)方式二:  使用emplace()d1.emplace(d1.begin(), 5);  在开始的位置插入5在空间不够的时候,两种方式都会开辟空间
*/
相关知识点: 
  • insert()在插入单个元素和多个元素的时候,返回的是插入位置的迭代器。(不同的编译器实现可能不一样)
  • 已经在vector中展示过 

6.deque容器元素的访问(和vector类似)

 代码:

/*
deque<int> d1{1,2,3,4,5};
deque的元素访问:
1. 使用[]:d1[0] = 10;cout << d1[2] << endl;
2. 使用at():d1.at(1) = 5;cout << d1.at(1) << endl;
3. 使用front()访问第一个元素d1.front() = 100;cout << d1.front() << endl;
4. 使用back()访问最后一个元素d1.back() =  50;cout << d1.back() << endl;
*/

7.  deque的迭代器(和vector使用方法是一样的)

 

 

至于迭代器的用法和vector是很类似的,此处就不在演示了。

8. deque容器删除元素(和vector类似) 

代码: 

/*deque<int> d1{1,2,3,4,5};deque删除元素:1. 使用erase()(1) d1.erase(d1.begin()); // 删除d1开始位置的元素(2) d1.erase(d1.begin(), d1.begin() + 2); // 删除迭代器区间[beg,end)内的元素,左闭右开的范围2. 使用clear()d1.clear()  // 删除所有的元素两者都不修改容器容量
*/
相关知识点: 
  • erase()函数在删除单个元素和多个元素的时候,都会返回被删除元素的下一个元素的迭代器。
  • 上面的使用,以及erase()使用的注意事项,和与循环结合删除元素时的注意事项,在vector中已经详细说明。 

 9.deque容器赋值(和vector类似)

代码: 

/*deque<int> d1{1,2,3,4,5};deque赋值操作:使用assign()1. d1.assign(5,1);  // 使用5个1覆盖容器中的原来数据2. deque<int> d2{10,11,12,13,14,15}; d1.assign(d2.begin(), d2.end()); // 使用d2中的迭代器范围[beg,end)中的元素覆盖原有数据3. int  arr[] = { 1,2,3,4,5 };  // 使用指针[ptr1,ptrt2)中的元素覆盖原来数据d1.assign(arr, arr + 2);4. d1.assign({ 5,6,7,8,9 }); // 使用列表中的数据覆盖原来数据使用赋值运算符重载d1 = d2;   // 使用d2中的值覆盖原来数据assign在空间不够的时候,会开辟空间
*/

10.resize()修改元素个数(和vector中的类似)

请看vector中的实现。 

11. deque()中的其它函数(和vector类似)

  •  swap() 函数可以交换两个deque容器的元素,并且会交换两个容器的容量
  • max_size() 函数会返回可以存储最大的元素数量。--> 并不是返回多少就一定能存储多少元素,得看电脑内存大小,编译器等因素都有影响。
  • empty() 函数可以判断容器中的元素个数是否为0,若为0返回true。

12. deque相对于vector函数的变动 

  • 增加了专门在首部添加元素和删除元素的函数。
  • 删除了data(),reserve(),capacity()这三个函数。 

13. deque容器的注意事项 

  • 在涉及到范围的时候,都是左闭右开的。
  •  初始化列表在c++11中新增的,如果不支持c++11那么就不能使用。(就是使用{}的地方,除数组之外)
  • deque中可以存放bool类型,vector中不可以存放。

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【EDK II】作为UEFI的实现,EDK II 的架构是什么样的

目录 前言 EDK II 架构 配置文件 结语 前言 基本输入输出系统 (Basic Input Output System, BIOS) 最早由 IBM&#xff08;International Business Machines Corporation) 公司于1981年提出并开发&#xff0c;后来成为个人计算机(PC)的标准固件接口。但受限于传统BIOS (Le…

春风吹又生的开源项目「GitHub 热点速览」

随着上周知名 Switch 开源模拟器 Yuzu&#xff08;柚子&#xff09;被任天堂起诉&#xff0c;该项目作者就删库了&#xff0c;但还是要赔偿任天堂数百万美元。此事还在 GitHub 上掀起了一波 Yuzu fork 项目的小浪潮&#xff0c;正所谓野火烧不尽&#xff0c;春风吹又生。 很多读…

应对恶意IP攻击的有效方法

在当今数字化时代&#xff0c;网络攻击已经成为了互联网安全的重大挑战之一。恶意IP攻击是网络安全领域中的一种常见威胁&#xff0c;它可能导致数据泄露、服务中断、系统瘫痪等严重后果。因此&#xff0c;有效地应对恶意IP攻击至关重要。IP数据云将深入探讨如何应对恶意IP攻击…

波奇学Linux:线程同步和信号量

cp是高效的&#xff1a;consumer在临界区&#xff0c;productor在非临界区&#xff0c;处于并发的过程 伪唤醒问题 假设只有唯一一个资源&#xff0c;消费进程一被唤醒获取资源&#xff0c;并释放锁&#xff0c;此时消费进程二竞争锁胜于生产进程&#xff0c;从pthtead_cond_…

【机器学习】从线性回归模型看一个简单的成本函数

&#x1f338;博主主页&#xff1a;釉色清风&#x1f338;文章专栏&#xff1a;机器学习&#x1f338;今日语录&#xff1a;事情不做&#xff0c;越想越难&#xff1b;事情做了&#xff0c;越做越容易。 从线性回归模型看一个简单的成本函数 &#x1f33c;引入&#xff1a;模型…

OpenCV的常用数据类型

OpenCV涉及的常用数据类型除包含C的基本数据类型,如&#xff1a;char、uchar&#xff0c;int、unsigned int,short 、long、float、double等数据类型外, 还包含Vec&#xff0c;Point、Scalar、Size、Rect、RotatedRect、Mat等类。C中的基本数据类型不需再做说明下面重点介绍一下…

OpenCV filter2D函数详解

OpenCV filter2D函数简介 OpenCV filter2D将图像与内核进行卷积&#xff0c;将任意线性滤波器应用于图像。支持就地操作。当孔径部分位于图像之外时&#xff0c;该函数根据指定的边界模式插值异常像素值。 该函数实际上计算相关性&#xff0c;而不是卷积&#xff1a; filter…

Linux基础命令[15]-less

文章目录 1. less 命令说明2. less 命令语法3. less 命令示例3.1 不加参数3.2 -N&#xff08;显示行号&#xff09;3.3 打开多个文件3.4 标记导航3.5 搜索内容 4. 总结 1. less 命令说明 less&#xff1a;用来分页查看文件&#xff0c;与 more 相比更加的灵活&#xff0c;并且…

rancher是什么

Rancher Labs是制作Rancher的公司。Rancher Labs成立于2014年&#xff0c;是一家专注于企业级容器管理软件的公司。它的产品设计旨在简化在分布式环境中部署和管理容器的过程&#xff0c;帮助企业轻松地采用容器技术和Kubernetes。Rancher Labs提供的Rancher平台支持Docker容器…

Windows kafka 简单集群搭建

Windows kafka 简单集群搭建 文章目录 Windows kafka 简单集群搭建1.环境说明2.Zookeeper集群搭建2.1 ZooKeeper下载2.2 ZooKeeper安装2.2.1 解压zookeeper-3.4.8.tar.gz2.2.2 进入conf目录下&#xff0c;复制zoo_sample.cfg为zoo.cfg2.2.3 修改zoo.cfg文件2.2.4 生成myid文件2…

定向广播助力西安南绕城高速高新至雁塔段可借用应急车道通行车辆分流诱导

HT-600定向广播助力西安南绕城应急车道分流&#xff01;定向广播是安装在高速公路上的一种大功率、远程定向传声设备&#xff0c;主要应用与高速公路事故易发段、高速公路分合流处等要害地点。 为了缓解绕城高速潮汐车流拥堵现象&#xff0c;着力服务群众便捷出行&#xff0c;西…

【C++ 学习】内存管理

1. new / delete 和 malloc / free 的区别? malloc / free 和 new / delete 的共同点&#xff1a;都是从堆上申请空间&#xff0c;并且需要用户手动释放。不同的地方是&#xff1a; malloc 和 free 是函数&#xff0c;new 和 delete 是操作符&#xff1b; malloc 申请的空间不…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的障碍物检测系统(深度学习代码+UI界面+训练数据集)

摘要&#xff1a;开发障碍物检测系统对于道路安全性具有关键作用。本篇博客详细介绍了如何运用深度学习构建一个障碍物检测系统&#xff0c;并提供了完整的实现代码。该系统基于强大的YOLOv8算法&#xff0c;并对比了YOLOv7、YOLOv6、YOLOv5&#xff0c;展示了不同模型间的性能…

NBlog整合OSS图库

NBlog部署维护流程记录&#xff08;持续更新&#xff09;&#xff1a;https://blog.csdn.net/qq_43349112/article/details/136129806 由于项目是fork的&#xff0c;所以我本身并不清楚哪里使用了图床&#xff0c;因此下面就是我熟悉项目期间边做边调整的。 目前已经调整的功能…

深度学习预备知识(线性代数)

介绍&#xff1a; 深度学习是一种机器学习的方法&#xff0c;涉及到大量的线性代数运算。线性代数是研究向量空间和线性映射的数学学科。在深度学习中&#xff0c;线性代数常用于表示和处理输入数据和模型参数。下面是一些深度学习中常见的线性代数概念和运算&#xff1a; 1. …

【DevOps基础篇之k8s】如何通过Kubernetes CKA认证考试

【DevOps基础篇之k8s】如何通过Kubernetes CKA认证考试 目录 【DevOps基础篇之k8s】如何通过Kubernetes CKA认证考试核心概念资源监控生命周期管理Cluster维护安全认证问题排查其他推荐超级课程: Docker快速入门到精通Kubernetes入门到大师通关课这些是我在准备CK

YOLOv5涨点优化:backbone改进 | TransXNet:聚合全局和局部信息的全新CNN-Transformer视觉主干| CVPR2024

💡💡💡本文独家改进:CVPR2024 TransXNet助力检测,代替YOLOv5 Backbone 改进结构图如下: 收录 YOLOv5原创自研 https://blog.csdn.net/m0_63774211/category_12511931.html 💡💡💡全网独家首发创新(原创),适合paper !!! 💡💡💡 2024年计算…

Day31:安全开发-JS应用WebPack打包器第三方库JQuery安装使用安全检测

目录 打包器-WebPack-使用&安全 第三方库-JQuery-使用&安全 思维导图 JS知识点&#xff1a; 功能&#xff1a;登录验证&#xff0c;文件操作&#xff0c;SQL操作&#xff0c;云应用接入&#xff0c;框架开发&#xff0c;打包器使用等 技术&#xff1a;原生开发&…

华为三层交换机:ACL的基本实验

实验要求&#xff1a; PC1不允许访问PC3&#xff0c;PC3可以访问PC1 分析问题&#xff1a; PC1不允许访问PC3&#xff0c;问题中含有“目标地址”则我们需要设置目标地址&#xff0c;这样基本ACL是不行的&#xff0c;必须使用高级ACL [sw1]acl ? INTEGER<2000-2999>…

国家网安教育技术产业融合发展试验区建设专家指导组莅临麒麟信安调研

3月12日下午&#xff0c;由教育部网络安全教学指导委员会秘书长&#xff08;专家组组长&#xff09;封化民、工业和信息化部规划司原司长肖华、中国现代国际关系研究院原副院长张力等领导组成的国家网安教育技术产业融合发展试验区建设专家指导组莅临麒麟信安及湖南欧拉生态创新…