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

目录

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中

  方式五:   调用拷贝构造函数
  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);  在开始位置插入5
 2. d1.insert(d1.begin(), 5,3); 在开始位置插入5个3
 3. 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)范围内的数据,范围为左闭右开
 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()在插入单个元素的时候,返回的是插入位置的迭代器。
  • insert()在插入多个元素的时候返回void
  • 已经在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中不可以存放。

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

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

相关文章

Linux搭建ftp服务

使用yum 进行安装 # 在线安装FTP yum install -y vsftpd 安装完成后查看ftp状态 # 查看ftp状态 systemctl status vsftpd.service # 启动ftp状态 重启&#xff1a;restart&#xff0c;停止&#xff1a;stop&#xff0c;开机自启&#xff1a;enable&#xff0c;关闭开机自启&…

【小黑送书—第十二期】>>一本书讲透Elasticsearch:原理、进阶与工程实践(文末送书)

Elasticsearch 是一种强大的搜索和分析引擎&#xff0c;被广泛用于各种应用中&#xff0c;以其强大的全文搜索能力而著称。 不过&#xff0c;在日常管理 Elasticsearch 时&#xff0c;我们经常需要对索引进行保护&#xff0c;以防止数据被意外修改或删除&#xff0c;特别是在进…

图片二维码能长期扫码展示吗?在线图片快速生码的文字教学

很多人在制作图片二维码的时候&#xff0c;比较关注的问题一个是扫码次数&#xff0c;另一个是二维码有效期&#xff0c;那么满足这两个需求的图片二维码该如何制作呢&#xff1f;想要制作不限制扫码次数并且长期有效的图片二维码&#xff0c;大家可以通过图片二维码生成器的功…

分库分表浅析原理

数据库存放数据大了&#xff0c;查询等操作就会存在瓶颈&#xff0c;怎么办&#xff1f; 1. 如果是单张表数据大了&#xff0c;可以在原有库上新建几张表table_0、table_1、table_2、.....table_n 写程序对数据进行分表&#xff1a; --这里提供一种一种分表策略,这里只需维护…

动态规划-背包问题 分析+代码

这里写自定义目录标题 介绍背包问题过程分析例题题目说明代码输出结果 介绍背包问题 背景&#xff1a;在现实生活中&#xff0c;我们常常会面临需要在有限空间内做出最优选择的情况&#xff0c;比如旅行时需要选择携带哪些物品&#xff0c;或者在资源有限的情况下选择最有利可图…

EASY-LASER激光对中仪维修E710镭射仪联轴器维修

Easy-Laser激光对中仪维修常见故障&#xff1a;触摸屏损坏&#xff08;屏碎&#xff0c;不显示&#xff0c;黑屏&#xff0c;蓝屏&#xff0c;无背光等&#xff09;&#xff0c;对中仪电路板损坏&#xff0c;对中仪接收装置电路板维修&#xff0c;对中仪发射控制装置电路板等均…

CubeMX使用教程(2)——如何点亮LED

在上一章&#xff0c;我们完成了CubeMX的环境配置&#xff0c;这一章我们通过CubeMX来完成点亮LED的工作。 通过LED原理图可知&#xff0c;如果我们要点亮LD1&#xff08;第一个灯&#xff09;&#xff0c;它对应开发板的PC8端口&#xff0c;因此我们应该在CubeMX中将PC8配置为…

OpenCV实战--人脸跟踪(级联分类器)

1、前言 人脸识别是基于人的脸部特征信息进行身份识别的--种生物识别技术,也是计算机视觉重点发展的技术。 机械学习算法诞生之后,计算机可以通过摄像头等输入设备自动分析图像中包含的内容信息,随着技术的不断发展,现在已经有了多种人脸识别的算法。 人脸跟踪是让计算机…

Java 语言“编译与解释并存”

程序语言的执行方式 将高级编程语言按照程序的执行方式分为两种&#xff1a; 编译型&#xff1a;编译型语言open in new window 会通过编译器open in new window将源代码一次性翻译成可被该平台执行的机器码。一般情况下&#xff0c;编译语言的执行速度比较快&#xff0c;开发…

微信jssdk获取定位计算距离

微信网页jssdk开发文档获取地理位置接口文档&#xff1a;https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#36 实现&#xff1a; const wx require(weixin-js-sdk) const jsApiList [ getLocation ]/*** 获取定位* param {*} configData 接口获取*…

云流化技术方案的优势

数字化的时代&#xff0c;许多新兴的技术都逐渐走进人们的视野&#xff0c;云流化作为一种新兴的技术在各个领域发挥着越来越重要的作用&#xff0c;也为我们带来了方便快捷的使用体验&#xff0c;尤其是在虚拟仿真和数字孪生领域&#xff0c;但是有的人可能听到这个词会比较陌…

armv8/armv9不同特权程序之间的跳转模型

目录 1、前言2、4个特权等级/4个安全状态之间的跳转模型3、启动时镜像之间的跳转模型4、runtime程序之间的跳转模型推荐 本文转自 周贺贺&#xff0c;baron&#xff0c;代码改变世界ctw&#xff0c;Arm精选&#xff0c; armv8/armv9&#xff0c;trustzone/tee&#xff0c;secur…

第二证券:金价创出历史新高 黄金主题类基金“熠熠闪光”

2024年3月以来&#xff0c;黄金价格走出了一轮波澜壮阔的行情。上海黄金&#xff08;SHFE黄金&#xff09;接连8日收涨&#xff0c;累计涨幅近6%&#xff0c;3月9日夜盘创出511.66元/克的前史最高价&#xff0c;最新收盘价为509.32元/克&#xff0c;相同是前史新高。 国际金价…

福州景湖佳园120平现代风格装修,简洁有层次。福州中宅装饰,福州装修

在现代风格的装修设计中&#xff0c;配色方案是决定整体氛围的关键因素。以福州景湖佳园的120平米装修案例为例&#xff0c;设计师巧妙地运用了灰、白、蓝三种颜色&#xff0c;打造出了一处既简洁又富有层次感的居住空间。 首先&#xff0c;灰色是现代风格中非常常见的一种色彩…

C++:继承与派生

为什么会有继承这样的语法呢&#xff1f;&#xff1f;试想这样一个场景&#xff1a;假设我们这个App需要去获取不同类型用户的数据&#xff0c;并进行分类&#xff0c;那么就需要我们去写对应不同的类&#xff0c;比如说学生、老师、军人、公司职工…………每个类都需要有名字、…

Python从0到100(三):Python中的变量介绍

前言&#xff1a; 零基础学Python&#xff1a;Python从0到100最新最全教程。 想做这件事情很久了&#xff0c;这次我更新了自己所写过的所有博客&#xff0c;汇集成了Python从0到100&#xff0c;共一百节课&#xff0c;帮助大家一个月时间里从零基础到学习Python基础语法、Pyth…

四川易点慧电子商务有限公司抖音小店安全正规

在如今网络购物日益普及的时代&#xff0c;消费者对于购物平台的选择越来越挑剔。四川易点慧电子商务有限公司抖音小店以其安全正规的经营模式&#xff0c;赢得了广大消费者的信赖和好评。本文将为您详细介绍四川易点慧电子商务有限公司抖音小店的优势和特点&#xff0c;让您在…

windows下pytorch的dataloader多进程(num_workers)问题,为何num_workers的值只能为0?

问题背景介绍 本人是windows系统&#xff0c;在使用torch.utils.data.Dataloader加载torchvision中的数据集时&#xff0c;将其中的形参num_workers设置为了大于0的数&#xff0c;然后出现以下错误。 原因 在 Windows 系统下&#xff0c;num_workers 参数在使用 PyTorch 的 t…

内部文档多维保密,如何做好内部文件的保密措施?

在企业的日常运营中&#xff0c;内部文档往往包含了公司的核心战略、财务数据、客户信息等重要内容。一旦这些文件泄露&#xff0c;可能会给企业带来无法估量的损失。 因此&#xff0c;做好内部文件的保密措施显得尤为关键。 这里有一件真实的案例可以参考一下。 某大型制造企…

网红老阳分享的蓝海赚钱项目,这三个真香!

在互联网经济飞速发展的当下&#xff0c;寻找蓝海项目成为了许多创业者和投资者的首要任务。近期&#xff0c;知名网红老阳分享了一些他认为具有巨大潜力的蓝海项目&#xff0c;其中包括RPO人力资源、视频号带货和Temu跨境电商。下面我们将对这三个项目进行详细解析。 老阳分享…