deque容器和list容器学习

2023-10-30

1.deque简介:

deque容器同样是一种顺序容器,你可以了解你的元素的存储位置,你可以安排你的元素的存储位置。和vector相比,deque可以实现用常数的时间在容器头部插入元素。同样deque也没有容量的概念,这是因为deque可以动态地增加连续空间,而不需要像vector那样,因为之前的空间不够用,必须重新找一块内存,把数据拷贝过去,然后销毁之前的。

虽然deque也提供了随机迭代器,但其迭代器并不是像vector中是一个普通的指针,其实是实现很复杂,所以,除非你的需求特别适合deque,可以优先考虑vector(当然我们在这只说他们两个,是因为它们都有随机存取能力)

ps:(由于个人能力问题,我们只是从大体的角度去看这个容器,达到在工作中能够随心所欲地使用就可以了,具体的实现代码,就不去挖掘,明白实现思路就好了)


2.deque的实现

2.1 deque内存管理的基本思路:

 deque源码(删减的)

template <class T>

class deque {

protected:

  iteraotr    start;//表示第一个节点  iterator是一个迭代器,我们到时候再看这个类

  iteraotr     finish;// 表现最后一个节点

protected:

  T**  map;  // 指向map, map是一个连续的空间, 其每个元素都是一个指向缓冲区的指针

 size_type map_size;   // map容量

}

 

这样其实就很明白了,在deque的类中,我们有一个指向指针数组的指针,根据这个指针我们可以找到,指针数组所在的地址,这个数组其实叫中控器。中控器中的每个元素,分别指向一个固定大小的连续空间,这段空间叫做缓冲区,我们的数据其实就是存储在缓冲区中的。当我们的数据多到盛不下时,就可以重新分配一些连续的内存扩大容量。

2.2 deque的迭代器


可以看出来,deque要想支持随机访问,它的跌代器就要设计的很复杂,首先要能够找到数据存储的地址,为了方便找到下一个数据的位置,如果在同一个缓冲区内它必须有两个指向缓冲区头和尾的指针。如果下一个位置在另外的缓冲区内,则必须知道中控器的地址。其实,人家的实现只是一种思路,你可以疑惑为什么迭代器还要用两个first和last指针呢,如果 没有它们,我是不是同样的可以了解到当前指针的位置,是不是已经到了末尾?假设没有它们,我们要想知道当前的位置,就必须用当前位置的指针,与中控器元素的指针做减法与缓冲区大小作比较,而且有时,我们还可能从缓冲区的末尾开始增加元素,很费劲的。所以,多管理一些指针会很方便。

 

2.3 存有元素的deque内存状态


deque类中还有两个start 和finish迭代器可以看出,在存入元素时,开始的时候是从中控器的最中间开始存的,start和finish分别指向第一个元素和最后一个元素的下一个位置。

了解的也就这些吧,思路很好,要是写一个这样的容器,现在肯定还没有这样的水平。所以改日再看看代码吧。

 

3. deque的一些成员函数

c.assign(beg,end)    将[beg; end)区间中的数据赋值给c。

c.assign(n,elem)    将n个elem的拷贝赋值给c。

c. at(idx)     传回索引idx所指的数据,如果idx越界,抛出out_of_range。

c.back()    传回最后一个数据,不检查这个数据是否存在。

c.begin()   传回迭代器中的第一个数据。

c.clear()     移除容器中所有数据。

c.empty()   判断容器是否为空。

c.end()   指向迭代器中的最后一个数据地址。

c.erase(pos)     删除pos位置的数据,传回下一个数据的位置。

c.erase(beg,end)     删除[beg,end)区间的数据,传回下一个数据的位置。

c.front()     传回第一个数据

c.insert(pos,elem)     在pos位置插入一个elem拷贝,传回新数据位置c.insert(pos,n,elem)     在pos位置插入>n个elem数据。无返回值c.insert(pos,beg,end)    在pos位置插入在[beg,end)区间的数据。无返回值c.max_size()     返回容器中最大数据的数量。

c.pop_back()     删除最后一个数据

c.pop_front()    删除头部数据。

c.push_back(elem)    在尾部加入一个数据。

c.push_front(elem)    在头部插入一个数据。

c.rbegin()    传回一个逆向队列的第一个数据。

c.rend()   传回一个逆向队列的最后一个数据的下一个位置。

c.resize(num)     重新指定队列的长度。

c.size()   返回容器中实际数据的个数。


4.list的简介

stl中的list其实是一个双向循环列表,既然是链表,就有链表的特点。不支持随机访问,但是插入和删除操作效率高。主要是它还有一些对链表的操作,可以很好的锻炼我们的编程能力。当然,有机会专门要写一篇这种东西。


5.list的内存结构


在没有数据时,list只有个空的节点,这个结点两个指针指向自己。

6.list的一些成员函数

assign()给list赋值

back()返回最后一个元素

begin()返回指向第一个元素的迭代器

clear()删除所有元素

empty()如果list是空的则返回true

end()返回末尾的迭代器

erase()删除一个元素

front()返回第一个元素

insert()插入一个元素到list中

max_size()返回list能容纳的最大元素数量

merge()      合并两个list

pop_back()删除最后一个元素

pop_front()删除第一个元素

push_back()在list的末尾添加一个元素

push_front()在list的头部添加一个元素

rbegin()返回指向第一个元素的逆向迭代器

remove()从list删除元素

remove_if()按指定条件删除元素

rend() 指向list末尾的逆向迭代器

resize()改变list的大小

reverse()把list的元素倒转

size()返回list中的元素个数

sort()list排序

splice()合并两个list

swap()交换两个list

unique()删除list中重复的元素

 

7.vector、list、deque、三个容器的选择:

1、如果你需要高效的随即存取,而不在乎插入和删除的效率,使用vector 
2、如果你需要大量的插入和删除,而不关心随即存取,则应使用list 
3、如果你需要随即存取,而且关心两端数据的插入和删除,则应使用deque。


参考资料:《STL源码剖析

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

deque容器和list容器学习 的相关文章

  • 多线程程序中的 std::string

    鉴于 1 C 03标准没有以任何方式解决线程的存在 2 C 03 标准将其留给实现来决定是否std string应该在其复制构造函数中使用 Copy on Write 语义 3 写时复制语义通常会导致多线程程序中不可预测的行为 我得出以下看
  • 如何使用模板模板参数为没有该方法所需的公共接口的 STL 容器实现通用方法

    问题陈述 为教育性的目的 实现适用于STL容器的方法printContainervector stack queue and deque 我提出了一个解决方案 但由于代码量过多 我不喜欢它 我为解决问题所做的事情 1 设计通用函数 期望容器
  • 通过值获取 std::queue 中元素的索引

    有没有一种简单的方法来获取元素在 a 中的位置std queue通过它在 C 中的值 例如 std queue
  • 重写标准库使用的内存分配方法? [复制]

    这个问题在这里已经有答案了 是否可以覆盖 STL 分配 管理和释放内存的方式 如果可能的话 人们会怎样做呢 有没有一种方法可以将处理原始内存的代码保留在一个类或文件中 我想对我的整个程序执行此操作 以便我可以跟踪内存使用情况 时间和生命周期
  • 区分映射和集合的模板

    在创建代码时common for set unordered set map and unordered map 我需要几种方法 其中处理实际上是不同的 我的问题是让编译器推断出要使用哪个实现 考虑这个例子 include
  • C++ 中的 Java HashSet 等效项

    我很好奇 C 中是否有类似于 Java HashSet 的东西 IE 一个快速查看的数据结构 因为我只会运行 contains e 在上面 同样 如果你能启发我如何做 contains 无论您提出什么数据结构 我都会非常感激 O 请不要发帖
  • 如何将 std::map 输出到二进制文件?

    我怎样才能输出一个std map到二进制文件 地图声明如下所示 map
  • 二维向量的迭代器

    如何为 2d 向量 向量的向量 创建迭代器 虽然你的问题是not非常清楚 我假设您的意思是 2D 向量表示向量的向量 vector lt vector
  • STL容器如何复制对象?

    我知道 STL 容器 比如vector添加对象时复制该对象 push back方法如下 void push back const T x 我很惊讶地发现它把该项目作为参考 我编写了一个示例程序来看看它是如何工作的 struct Foo Fo
  • 在 C++ 中将惰性生成器实现为forward_iterator

    MyGenerator 表示 可能 有限的整数序列 计算成本很高 所以我不想预先生成它们并将它们放入容器中 struct MyGenerator bool HasNext int Next 要打印全部 MyGenerator generat
  • STL(标准模板库)中使用的设计模式

    我正在学习STL和设计模式 我想知道是否有任何文档或链接可以解释如何在 STL 中实现设计模式 我做了谷歌但无法获得太多数据 我希望你的意思是 哪些设计模式可以在STL中识别 STL 堆栈是一个容器适配器 适配器是一种设计模式 迭代器也是一
  • 是否有可能在 C++ 中获取 std::array 的子数组?

    我想做类似的事情 std array
  • 了解 std::swap()。 tr1::_Remove_reference 的目的是什么?

    在 VS10 的 STL 实现中 有以下 std swap 变体的代码 TEMPLATE FUNCTION Move template
  • 如何将 BOOST_FOREACH 与两个 std::map 一起使用?

    我的代码基本上如下所示 std map
  • std::enable_if 和 std::enable_if_t 有什么区别?

    C 14 引入std enable if t 它和有什么区别std enable if 使用上有什么优点或者区别吗std enable if t std enable if t 是 std enable if 的内部 type 的类型别名
  • C++类名冲突

    我现在正在做一个项目 需要整合两个子项目 项目A是用C 编写的 项目B是用C编写的 一个问题是 在项目B中 有一个名为vector它是由其作者创建的 在项目 A 中 std vector in STL用来 因为项目B以后可能会更新 所以我不
  • 可能的 std::async 实现错误 Windows

    看来 std async 的 Windows 实现存在错误 在重负载下 大约每秒启动 1000 个异步线程 异步任务永远不会被调度 并且等待返回的 future 会导致死锁 请参阅这段代码 使用延迟启动策略而不是异步进行修改 Bundlin
  • std::map 和二叉搜索树

    我读过 std map 是使用二叉搜索树数据结构实现的 BST 是一种顺序数据结构 类似于数组中的元素 它将元素存储在 BST 节点中并按其顺序维护元素 例如如果元素小于节点 则将其存储在节点的左侧 如果元素大于节点 则将其存储在节点的右侧
  • 是否允许将 std::vector 的元素插入到同一向量中?

    考虑以下insert and emplace的成员函数std vector
  • std::vector::data() 的状态是什么?

    我刚刚意识到我一直在使用std vector data 出于与 std string 的相似性 但一位同事指出它不是标准的 显然 Gcc 实现了它 但是查看它的包含文件 我发现了这样的注释 GLIBCXX RESOLVE LIB DEFEC

随机推荐

  • Vue自定义指令

    目录 1 自定义指令注册 1 1 全局注册 1 2 局部注册 2 自定义指令写法 2 1 对象式 常用 2 2 函数式 3 总结 1 自定义指令注册 1 1 全局注册 Vue directive name 1 2 局部注册 directiv
  • 计算机怎么更改桌面图标大小,win7系统桌面图标怎么设置大小 win7电脑桌面图标大小更改方法...

    win7系统在使用的时候不知道大家有没有遇上这样的问题 就是桌面图标的大小不符合我们的审美 那么遇上这种情况要怎么解决呢 下面小编就跟大家说说处理的方法 具体的解决方法 这种方法是最快捷的方法 我们可以在电脑桌面上 按住Ctrl键不放 然后
  • Qt 子线程中使用UI线程

    方案起源 最近做了一个Excel保存图表的项目 因为不能直接用Excel的图表 会直接暴露计算数据 所以采用的是QCharts生成的表格 但是QCharts的问题是 调用QChartView setChart接口之后 会出现不在同一个线程的
  • 模拟电路设计(5)--- J-FET的特性曲线

    上篇我们分析了J FET的结构和工作原理 今天我们来说说J FET的输出 转移特性曲线 J FET的输出特性曲线 由图中可以看出 J FET的输出特性曲线分为四个区域 可变电阻区 线性放大区 截止区和击穿区 下面分别来说说 1 截止区 在N
  • Vue第10天笔记:Vue动画(了解)、yarn命令的安装、webpack:介绍、基本步骤使用、npm中 --save和 --save-dev的区别、scripts的使用、配置到文件中、自动生成插件

    前一天复习 1 自定义指令 1 定义使用 Vue directive 指令名 指令的配置对象 2 五个钩子函数 bind inserted update 3 钩子函数的参数 el 指令所在的元素 binding 指令相关的信息对象 1 na
  • 【数模】奇异值分解SVD和图形处理

    介绍奇异值分解在图形压缩中的运用 并将简单介绍下Matlab对于图形和视频的处理 一 奇异值分解介绍 1 1 基本概念 奇异值分解 Singular Value Decomposition 以下简称SVD 是线性代数中一种重要的矩阵分解 U
  • C++ STL三大常用容器

    看到一篇文章觉得对不熟悉STL容器特性和使用选择的人来说很友好 就收藏和学习下 https blog csdn net qq 44943840 article details 121990808 C 中的容器可以分为好多种 常见的有顺序容器
  • 计算机网络(一)----概述

    概述 功能 组成 分类 性能指标 一 计算机网络的概述 1 网络的概念网络是由若干结点和链路组成 结点可以是计算机 集线器 交换机 路由器等 链路可以是有线链路或无线链路 如电信网络 电话 电报 传真服务 有限电视网络 观看电视节目 计算机
  • C++矩阵运算类(Matrix.h)

    这个类数据类型是double 包含了常用的矩阵计算 多数方法经过实践验证 也难免有不足之处 如有发现欢迎指出 https github com ims0 comTutor tree master matrix include
  • 晶振的负载电容与外接电容的区别与关系

    经常遇到有人把晶振的负载电容与外接电容混淆 甚至还有人误以为这是指同样的参数 这里需要特别指出的是 若你这样想 就大错特错了 下面就为您进行分析与区分 负载电容指的是晶振的一个内部重要电气参数 一般情况下 对功耗不太敏感的电子设备PCBA上
  • Stable Diffusion模型阅读笔记

    Stable Diffusion模型 什么是Stable Diffusion模型 一般而言 扩散是在图像中反复添加小且随机的噪声 与之相反 Stable Diffusion模型是一种将噪声生成为图像的机器学习模型 经过训练 它可逐步对随机高
  • leetcode 链表相交

    面试题 02 07 链表相交 力扣 LeetCode leetcode cn com 在看别人的题解之前我有过两个思路 1 最容易想到的就是对链表A中的每个元素都在B中查找 如果找到了就是相交点 显然这种方法的时间复杂度比较高 leetco
  • 闲鱼新手如何快速卖货 咸鱼赚钱排名优化技巧

    闲鱼现在很多人都有了解 对于高价值自己没用的二手物品 甚至全新物品在这个平台出售 闲鱼 对于大多数人来说只是一个卖二手和买二手的app 哪里有人 哪里就有流量 哪里有流量 哪里就存在引流的空间 小满老师介绍以下八个方法 供大家学习 teac
  • Spring三种bean注入方式

    Spring中依赖注入有三种注入方式 一 构造器注入 二 设值注入 setter方式注入 三 Feild方式注入 注解方式注入 一 构造器注入 构造器注入顾名思义就是在程序组件中实现构造器 构造器可以是一个也可以是多个 废话不多说 直接上代
  • flex 子元素占满剩余高度 与 flex:1 的子元素 overflow:hidden 失效

    这几天使用flex开发大屏 遇到一个印象比较深的问题就是flex的子元素 在其他兄弟元素的高度不定的情况下 如何占满父元素的剩余空间 效果图 要点就是 1 父元素要设置 display flex 2 父元素的主轴方向设置为从上到下 flex
  • Dockerfile 中 ENTRYPOINT 的使用

    先占个坑 以免忘记 有空了来填
  • 2、Java基础-NIO、IO、ThreadLocal类

    1 IO和NIO 1 1 传统IO和NIO区别在哪 Java NIO和IO之间最大的区别在 IO是面向流的 而NIO是面向缓存区buffer的 Java NIO是非阻塞式的 意味着使用一个线程向某通道发送一个请求读取数据 如果buffer中
  • Squid日志分析与访问控制详解

    squid日志分析与访问控制 squid的日志系统能够帮助我们查看访问者的记录 包括来访者Internet的站点信息 时间占用信息 排名 连接次数和访问量 是一个很完善的日志系统 squid常用日志分为如下两个 分别是access log
  • 笔试题14:用TCP通信模型创建一个Web服务器(源码)

    我们都知道 IIS Apache和tomcat等Web服务器可以用来创建Web站点 负责接受客户端浏览器的HTTP请求 那么 他们是如何实现的呢 其实基本原理是采用TCP通信模型 下面给出一个采用Java的TCP编程API创建的简易Web服
  • deque容器和list容器学习

    1 deque简介 deque容器同样是一种顺序容器 你可以了解你的元素的存储位置 你可以安排你的元素的存储位置 和vector相比 deque可以实现用常数的时间在容器头部插入元素 同样deque也没有容量的概念 这是因为deque可以动