C++ STL 容器 deque

目录

  • 1. deque 对象
    • 1.1 内部表示
    • 1.2 底层数据结构
    • 1.3 分段连续
    • 1.4 重新分配
  • 2. deque 迭代器


本文测试环境 gcc 13.1

1. deque 对象

1.1 内部表示

deque 为我们提供了一个双端队列,即可以在队头进行 push、pop,可以在队尾进行 push、pop

deque 容器擅长的就是在头部和尾部添加或删除元素

vector 是一段连续的内存空间,当需要重新分配时,转移到了另一段连续的内存空间,而 deque 的实现比较复杂,deque 底层维护的是一段段连续的内存空间

首先看看 deque<T> 对象的内部表示
在这里插入图片描述
因为需要维护一段段的连续空间,里面保存了很多指针,其中的 iterator 是 deque 的迭代器
sizeof(deque<int>) = 80,相比 vector 大很多

1.2 底层数据结构

下图是具体的模型
在这里插入图片描述
假设现在有一个 deque 对象保存了 1, 2, …, n, n+1, n+2 这样一个序列,那么它们可能就像如图所示的分布情况

左边是一个映射表,表中每一个指针指向一段连续的内存空间,通过这个表来将所有分段联系起来

右边是两段连续的内存空间,用来存放实际的元素,每一段空间所能容纳的元素个数是相同的。图中 0 ~ n 存放在一块,n + 1 存放在另一块,整个序列不是连续的,而是分段连续的

再看看 iterator ,node 指向映射表中的一个数据,来定位这段空间,first 和 last 分别指向这段空间的首地址和可用空间的末尾地址,iterator start 的 cur 指针指向第一个元素,而 iterator finish 的 cur 指针指向的是最后一个元素的下一个位置

1.3 分段连续

iterator 中 node 的作用就很关键了,想从一段空间跳到下一段空间,就需要将 node + 1 ,这样 node 指向了下一段内存空间,迭代器就可以访问下一段空间里的元素了,这就是 deque 实现的分段连续

底层 deque 申请了一段段的空间,通过这个 map 映射表,让用户感觉就是一段完整的连续空间

当头部或尾部要超出容量时,就需要分配新的一段空间,建立一个新的映射关系,在新的一段空间里构造新元素

1.在头部添加元素:
在这里插入图片描述
如图,现在想 push_front(0) 在头部添加一个元素,因为再添加已经超出空间,所以需要分配一个新的空间,添加之后情况如下
在这里插入图片描述
新添加的 0 在新空间的末尾

2.在末尾添加元素:
在这里插入图片描述
如图,现在想 push_back(n+1) 在末尾添加一个元素,但是现在的空间的元素个数已经用完了,需要分配一个新空间,添加之后情况如下
在这里插入图片描述
新添加的 n + 1 在新空间的首部

1.4 重新分配

vector 的重新分配需要将元素从旧空间转移至新空间

而 deque 的重新分配是指 map 映射表用完了,需要申请新空间容纳更多的映射关系,而实际存放元素的那些空间并不需要处理,只需要将旧映射表中的指针拷贝到新映射表就行了

2. deque 迭代器

deque 对象中已经使用了 start 和 finish 来定位首尾元素了,下面我们看看 deque 迭代器的具体实现

template<typename _Tp, typename _Ref, typename _Ptr>
struct _Deque_iterator
{
	_Elt_pointer _M_cur;	// T*
	_Elt_pointer _M_first;
	_Elt_pointer _M_last;
	_Map_pointer _M_node;	// T**
}

deque 迭代器实现为随机访问迭代器

cur 指针指向的就是具体的元素,通过 cur 就能访问元素了

 _GLIBCXX_NODISCARD
reference
operator*() const _GLIBCXX_NOEXCEPT
{ return *_M_cur; }

_GLIBCXX_NODISCARD
pointer
operator->() const _GLIBCXX_NOEXCEPT
{ return _M_cur; }

++ – 也就是 cur 指针移动,这里就是要考虑 cur 到达 fisrt 或 last 需要跳转到另一段空间中,这就需要改变 node 了,同时修改 first 和 last ,如果 cur 需要跳转到前一段空间,那么 cur 应该指向这段空间的末尾也就是 last - 1,如果是跳转下一段空间,那么 cur 应指向这段空间的首地址也就是 first

_Self&
operator++() _GLIBCXX_NOEXCEPT
{
	++_M_cur;
	if (_M_cur == _M_last)
	{
		_M_set_node(_M_node + 1);
		_M_cur = _M_first;
	}
	return *this;
}

_Self&
operator--() _GLIBCXX_NOEXCEPT
{
	if (_M_cur == _M_first)
	{
		_M_set_node(_M_node - 1);
		_M_cur = _M_last;
	}
	--_M_cur;
	return *this;
}

跳转到另一个空间,修改 node

void
_M_set_node(_Map_pointer __new_node) _GLIBCXX_NOEXCEPT
{
	_M_node = __new_node;
	_M_first = *__new_node;
	_M_last = _M_first + difference_type(_S_buffer_size());
}

这样就可以在分段的空间上遍历所有元素了

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

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

相关文章

电弧的产生机理

目录&#xff1a; 1、起弧机理 2、电弧特点 3、电弧放电特点 4、实际意义 1&#xff09;电力开关装置 2&#xff09;保险丝 1、起弧机理 电弧的本质是一种气体放电现象&#xff0c;可以理解为绝缘情况下产生的高强度瞬时电流。起弧效果如下图所示&#xff1a; 在电场的…

pyplot+pandas实现操作excel及画图

1、安装jupyter lab pip install jupyterlab # 启动 建议在指定的项目文件夹下 开启cmd窗口并执行 jupyter lab 启动后会自动打开浏览器访问 2、安装依赖 pip install matplotlib pip install xlrd pip install pandas 3、读取excel import pandas as pddf pd.read_excel(hi…

一文带你了解什么是国际短信

什么是国际短信&#xff1f; 国际短信&#xff0c;也叫国际短消息&#xff0c;是指中国大陆以外的国家或地区运营商与用户之间发送和接收短信息的业务&#xff0c;是一种实现国际间沟通交流与信息触达的便捷方式&#xff0c;可广泛应用于出海游戏、跨境电商、在线社交、实体零…

「探索C语言内存:动态内存管理解析」

&#x1f320;先赞后看&#xff0c;不足指正!&#x1f320; &#x1f388;这将对我有很大的帮助&#xff01;&#x1f388; &#x1f4dd;所属专栏&#xff1a;C语言知识 &#x1f4dd;阿哇旭的主页&#xff1a;Awas-Home page 目录 引言 1. 静态内存 2. 动态内存 2.1 动态内…

比特币上最有价值的BRC-20,你了解吗?

BRC20 是比特币网络上发行同质化Token 的实验性格式标准&#xff0c;由domodata 于2023 年3 月8 日基于 Ordinal 协议创建。 类似于以太坊的 ERC20 标准&#xff0c;它规定了以太坊上发行 Token 的名称、发行量、转账等功能&#xff0c;所有基于以太坊开发的 Token 合约都遵守这…

计算机视觉——DiffYOLO 改进YOLO与扩散模型的抗噪声目标检测

概述 物体检测技术在图像处理和计算机视觉中发挥着重要作用。其中&#xff0c;YOLO 系列等型号因其高性能和高效率而备受关注。然而&#xff0c;在现实生活中&#xff0c;并非所有数据都是高质量的。在低质量数据集中&#xff0c;更难准确检测物体。为了解决这个问题&#xff…

axios 请求中断和请求重试

请求中断​ 请求已经发出去了&#xff0c;如何取消掉这个已经发出去的请求&#xff1f; 微信扫码体验一下 &#xff08;说不定哪天你就用得上&#xff09; 用途&#xff1a; 比如取消正在下载中的文件点击不同的下拉框选项&#xff0c;向服务器发送新请求但携带不同的参数&…

解决系统报错:此应用无法在你的电脑上运行

在开发过程中不知从何时起&#xff0c;使用电脑时过程中不断的都显示“此应用无法在你的电脑上运行”&#xff0c;让人非常恶心&#xff0c;一直以为是系统误操作了什么或误安了软件 百度的答案就是让你找到报错的软件用兼容模式运行。而我连报错的软件都不知道&#xff0c;让人…

盲人盲杖:科技革新,助力视障人士独立出行

在我们的社会中&#xff0c;盲人朋友们以其坚韧的精神风貌&#xff0c;生动诠释着生活的多样与可能。然而&#xff0c;当我们聚焦于他们的日常出行&#xff0c;那些普通人视为寻常的街道、路口&#xff0c;却成为他们必须面对的严峻挑战。如何切实提升盲人盲杖的功能&#xff0…

怎么检查3d模型里的垃圾文件---模大狮模型网

在处理3D模型时&#xff0c;经常会遇到一些不必要的垃圾文件&#xff0c;它们可能占据硬盘空间&#xff0c;增加文件大小&#xff0c;甚至影响模型的性能和质量。因此&#xff0c;及时检查和清理这些垃圾文件对于优化工作流程和提高效率非常重要。在本文中&#xff0c;我们将介…

利用Python进行大规模数据处理【第173篇—数据处理】

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 利用Python进行大规模数据处理&#xff1a;Hadoop与Spark的对比 随着数据量的不断增长&…

CSS中position属性总结

CSS中position属性的总结 如果我的文章看不懂&#xff0c;不要犹豫&#xff0c;请直接看阮一峰大佬写的文章 https://www.ruanyifeng.com/blog/2019/11/css-position.html 1 干嘛用的 用来定位HTML元素位置的&#xff0c;通过top、bottom、right、left定位元素 分别有这些值&a…

【DM8】ODBC

官网下载ODBC https://www.unixodbc.org/ 上传到linux系统中 /mnt下 [rootstudy ~]#cd /mnt [rootstudy mnt]# tar -zxvf unixODBC-2.3.12.tar.gz [rootstudy mnt]# cd unixODBC-2.3.12/ [rootstudy unixODBC-2.3.12]# ./configure 注意&#xff1a;若是报以上错 则是gcc未安…

双向链表(带头双向循环链表)的实现

前言&#xff1a;前面实现的单向链表&#xff0c;全称是不带头单向不循环链表。这里实现带头双向不循环链表&#xff0c;比单向链表好实现一点。 目录 链表的分类 单向链表与双向链表的比较&#xff1a; 双向链表的节点的定义&#xff1a; 多文件实现&#xff1a; List.h来…

B007-二维数组方法

目录 二维数组一维数组回顾二维数组定义与创建二维数组的遍历二维数组堆栈图特殊的char数组 方法main方法认识自定义方法调用同类中方法调用不同类中方法方法的参数方法的返回值方法签名方法重载 二维数组 一维数组回顾 二维数组定义与创建 二维数组的遍历 /*** 二维数组:* …

230元的通配符证书是最便宜的吗

随着互联网的发展&#xff0c;越来越多的人认为需要保护用户在网站中传输的数据&#xff0c;因此各个数字证书颁发机构颁发各种数字证书来为网站传输信息进行加密。其中通配符SSL证书是比较受欢迎的一款域名数字证书&#xff0c;这款SSL证书可以用一张证书保护主域名以及主域名…

为什么选择TikTok直播专线而不是节点?

TikTok直播已成为许多商家的重要营销手段&#xff0c;而网络质量作为营销直播效果的关键因素&#xff0c;使得商家们开始应用TikTok直播专线。虽然与节点相比&#xff0c;专线的价格稍高&#xff0c;但更多商家都倾向于选择TikTok直播专线。那么&#xff0c;为什么TikTok直播更…

Nginx内存池相关源码剖析(一)总览

剖析nginx的内存池源码&#xff0c;讲解原理实现以及该内存池设计的应用场景 介绍 Nginx内存池是Nginx为了优化内存管理而引入的一种机制。在Nginx中&#xff0c;每个层级&#xff08;如模板、TCP连接、HTTP请求等&#xff09;都会创建一个内存池进行内存管理。当这些层级的…

5款开源、美观、强大的WPF UI组件库

前言 经常看到有小伙伴在DotNetGuide技术社区微信交流群里提问&#xff1a;WPF有什么好用或者好看的UI组件库&#xff1f;,今天大姚给大家分享5款开源、美观、强大、简单易用的WPF UI组件库。 WPF介绍 WPF 是一个强大的桌面应用程序框架&#xff0c;用于构建具有丰富用户界面…

mysql 5.7分组报错问题 Expression #1 of ORDER BY clause is not in GROUP BY clause

解决方案&#xff1a; select version(), sql_mode;SET sql_mode(SELECT REPLACE(sql_mode,ONLY_FULL_GROUP_BY,)); 完美的解决方案是&#xff1a; 1 show variables like "sql_mode"; 2 3 set sql_mode; 4 set sql_modeNO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABL…