C++STL——deque容器详解

news2024/11/19 6:11:47

在这里插入图片描述
纵有疾风起,人生不言弃。本文篇幅较长,如有错误请不吝赐教,感谢支持。

💬文章目录

    • 一.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个整型元素6
	d3.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 4
	deque<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 0

	deq.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 5

	v.insert(v.begin() + 1, 2, 100);//在第二个元素插入2个100
	printdeque(v);//1 100 100 2 3 4 5

	v.pop_front();//头部删除一个元素
	v.pop_back();//尾部删除一个元素
	printdeque(v);//100 100 2 3 4
	cout << "-------------" << endl;
	v.erase(v.begin());//删除第一个元素
	printdeque(v);//100 2 3 4

	deque<int>::const_iterator it = v.erase(v.begin() + 1, v.end() - 1);//删除从第二个元素到倒数第二个元素,返回下一个有效迭代器
	printdeque(v);//100 4

	v.insert(it, 66);
	printdeque(v);//100 66 4

	v.clear();//清空容器
}
int main()
{
	test();
	return 0;
}

在这里插入图片描述

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

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

相关文章

使用IPSEC VPN 在有防火墙的场景和有NAT转换的场景下实现隧道通信实验

目录 一、在有防火墙的场景 1、为所有设备配置对应ip地址&#xff1a; 2、进入两个防火墙实现公网互通 3、测试公网是否互通 4、进入SW1配置IPSEC VPN 5、进入SW2配置IPSEC VPN 6、配置策略方向ESP的流量 7、尝试使用PC1访问PC2 二、在有NAT地址转换的场景 1、为新增加…

C语言中的数据类型有哪些?

有符号数signed可以存储负数&#xff0c;无符号数呢只能存储非负数 我们要考虑两个问题。 第一个问题是要存储的这个整数&#xff0c;它是一个多大的范围&#xff0c;比如说要存储一个五。还有比如说我可能要算个数65535&#xff0c;或者说我要算出一个数65536&#xff0c;可能…

Cilium系列-11-启用带宽管理器

系列文章 Cilium 系列文章 前言 将 Kubernetes 的 CNI 从其他组件切换为 Cilium, 已经可以有效地提升网络的性能. 但是通过对 Cilium 不同模式的切换/功能的启用, 可以进一步提升 Cilium 的网络性能. 具体调优项包括不限于: 启用本地路由(Native Routing)完全替换 KubeProx…

P-DQN:离散-连续混合动作空间的独特算法

一、说明 本文首先说明DQN是个什么概念&#xff0c; DQN&#xff08;Deep Q-Network&#xff09;是一种基于深度学习的强化学习算法&#xff0c;在游戏AI中表现优异&#xff0c;如AlphaGo。然后说明人物动作预测的算法实现方法。 二、关于DQN的概念和实验 DQN&#xff08;Deep …

混合精度训练中的内存占用

结论&#xff1a; 在模型训练中&#xff0c;fp16会比fp32快很多&#xff0c;因此&#xff0c;一般会使用fp16的参数进行模型的前向和后向计算。然而&#xff0c;在进行梯度累加的时候&#xff0c;fp16往往会精度不够&#xff0c;无法满足计算需求。因此&#xff0c;会在反向计…

SOLIDWORKS等轴测剖切视图的创建技巧

在SOLIDWORKS工程图中&#xff0c;经常会用到等轴测剖切视图来显示零件或装配体的内部结构&#xff0c;下面介绍一下两种创建方式&#xff0c;供大家参考&#xff0c;以下图为例。 方法一 第一步&#xff0c;打开零件&#xff0c;创建一个切除拉伸的配置&#xff0c;该配置为 …

全网超细,Jenkins持续集成-自动化测试(详细整理)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 执行集成构建 持…

计算机top命令

top 快捷键 1 核心参数 1 1 参考资料 [1]. https://blog.csdn.net/weixin_45465395/article/details/115728520 [2].https://www.cnblogs.com/liushui-sky/p/13224762.html

为了规避风险,如何给大模型打水印?

大型语言模型&#xff0c;如最近开发的ChatGPT&#xff0c;可以撰写文件、创建可执行代码和回答问题&#xff0c;通常具有人类般的能力。 随着这些大模型的应用越来越普遍&#xff0c;越来越大的风险也显现了出来&#xff0c;它们可能被用于恶意目的。这些恶意目的包括&#xf…

uni-app选择器( uni-data-picker)选择任意级别

背景说明 uni-app 官方的插件市场有数据驱动选择器&#xff0c;可以用作多级分类的场景。引入插件后&#xff0c;发现做不到只选择年级&#xff0c;不选择班级&#xff08;似乎&#xff0c;只能到最后子节点了&#xff09;。 需求中&#xff0c;有可能选择的不是叶子。比如&a…

渣罐炉倾翻液压系统比例阀控制器

渣罐炉倾翻液压系统是一种用于渣罐炉倾翻的液压系统&#xff0c;由液压泵、油缸、阀组、油箱、管路等组成。 2. 启动液压泵&#xff0c;将液压油输送到油缸。 总之&#xff0c;渣罐炉倾翻液压系统具有操作简便、高效稳定等特点&#xff0c;适用于各种类型的渣罐炉倾翻。

SpringBoot+Vue开发笔记

参考&#xff1a;https://www.bilibili.com/video/BV1nV4y1s7ZN?p1 ----------------------------------------------------------概要总结---------------------------------------------------------- 1、MVC架构&#xff1a; View&#xff1a;与用户交互 Controller&…

浅谈下API初步认知

当我们谈论API&#xff0c;我们指的是应用程序接口&#xff08;Application Programming Interface&#xff09;。API允许不同的软件应用程序之间互相通信和交互。它定义了一组规定和协议&#xff0c;用于确定数据传输和请求的格式、方法和功能。 API的作用是在软件开发中提供一…

运动蓝牙耳机什么款式好、适合运动的蓝牙耳机推荐

夏天到了&#xff0c;越来越多的年轻人会选择在一天的忙碌之后通过简单的运动缓解疲劳。而在运动装备的选择上&#xff0c;除了常规的衣服、鞋之外&#xff0c;耳机也成为了当下年轻群体的必备项&#xff0c;尤其是在运动的过程中听听喜欢的音乐或者电台能够更好地放松身心。那…

Go init 顺序 使用建议

init函数的主要作用&#xff1a; 初始化不能采用初始化表达式初始化的变量。程序运行前的注册&#xff0c;例如初始化数据库链接。实现sync.Once功能。其他 init函数的主要特点&#xff1a; init函数先于main函数自动执行&#xff0c;不能被其他函数调用&#xff1b;init函数…

LeetCode每日一题Day3——1. 两数之和

✨博主&#xff1a;命运之光 &#x1f984;专栏&#xff1a;算法修炼之练气篇&#xff08;C\C版&#xff09; &#x1f353;专栏&#xff1a;算法修炼之筑基篇&#xff08;C\C版&#xff09; &#x1f433;专栏&#xff1a;算法修炼之练气篇&#xff08;Python版&#xff09; …

Java编程常用数据转换:String与int互转、Date与String互转、BigDecimal与int比较

一、String与Int互转 在 Java 中要将 String 类型转化为 int 类型时&#xff0c;需要使用 Integer 类中的 parseInt() 方法或者 valueOf() 方法进行转换。 String str "555555555"; int a Integer.parseInt(str); // 方式1 int b Integer.valueOf(str).intValu…

从虚拟到现实:数字孪生助力建筑创新

随着科技的不断进步&#xff0c;数字孪生技术正逐渐成为建筑行业的新宠。数字孪生是一种将实体世界与数字世界相结合的技术&#xff0c;通过将现实世界中的物体、系统或过程以数字化的方式进行建模和仿真&#xff0c;实现了真实世界与虚拟世界的互通。 在建筑行业中&#xff0c…

酷开系统 | 酷开科技,让数据变得更有价值!

身处信息时代&#xff0c;我们每个人时刻都在生成、传递和应用数据&#xff0c;数据已经成为了现代社会中宝贵的资源之一&#xff0c;而在人工智能领域&#xff0c;数据更是被称为人工智能的“燃料”。 而在AI的发展中&#xff0c;只有拥有高质量、多样性且充分代表性的数据集…

Sqli-labs1~65关 通关详解 解题思路+解题步骤+解析

Sqli-labs 01关 (web517) 输入?id1 正常 输入?id1 报错 .0 输入?id1-- 正常判断是字符型注入&#xff0c;闭合方式是这里插一句。limit 100,1是从第100条数据开始&#xff0c;读取1条数据。limit 6是读取前6条数据。 ?id1 order by 3-- 正常判断回显位有三个。?id…