C++ STL中各容器内存、优劣的分析

2023-05-16

STL有三大核心部分:容器(Container)、算法(Algorithms)、迭代器(Iterator)。以下介绍容器相关内容:

各种容器的元素在内存中的储存方式

1、vector(向量):相当于数组,但其大小可以不预先指定,并且自动扩展。它可以像数组一样被操作,

由于它的特性我们完全可以将vector 看作动态数组。在创建一个vector 后,它会自动在内存中分配一块连续的

内存空间进行数据存储,初始的空间大小可以预先指定也可以由vector 默认指定,这个大小即capacity ()函数

的返回值。当存储的数据超过分配的空间时vector 会重新分配一块内存块,但这样的分配是很耗时的,效率非常低。

2、deque(队列):它不像vector 把所有的对象保存在一块连续的内存块,而是采用多个连续的存储块,并且在一个

映射结构中保存对这些块及其顺序的跟踪。向deque 两端添加或删除元素的开销很小,它不需要重新分配空间。
3、list(列表):是一个线性链表结构,它的数据由若干个节点构成,每一个节点都包括一个信息块(即实际存储的数据)、

一个前驱指针和一个后驱指针。它无需分配指定的内存大小且可以任意伸缩,这是因为它存储在非连续的内存空间中,

并且由指针将有序的元素链接起来。
4、set, multiset, map, multimap 是一种非线性的树结构,具体的说采用的是一种比较高效的特殊的

平衡检索二叉树—— 红黑树结构。

各种容器优劣分析

1、Vector:
优点:
  A、支持随机访问,访问效率高和方便,它像数组一样被访问,即支持[ ] 操作符和vector.at()。
  B、节省空间,因为它是连续存储,在存储数据的区域都是没有被浪费的,但是要明确一点vector 大多情况下并不是满存的,在未存储的区域实际是浪费的。
缺点:
  A、在内部进行插入、删除操作效率非常低。
  B、只能在vector 的最后进行push 和pop ,不能在vector 的头进行push 和pop 。
  C、 当动态添加的数据超过vector 默认分配的大小时要进行内存的重新分配、拷贝与释放,这个操作非常消耗能。

2、List:
优点:
  不使用连续的内存空间这样可以随意地进行动态操作,插入、删除操作效率高;
缺点:
  A、不能进行内部的随机访问,即不支持[ ] 操作符和vector.at(),访问效率低。
  B、相对于verctor 占用更多的内存。

3、Deque:
优点:
  A、支持随机访问,方便,即支持[ ] 操作符和vector.at() ,但性能没有vector 好;
  B、可以在两端进行push 、pop 。
缺点:
  在内部进行插入、删除操作效率低。
综合:
    vector 的查询性能最好,并且在末端增加数据也很好,除非它重新申请内存段;适合高效地随机存储。 
list 是一个链表,任何一个元素都可以是不连续的,但它都有两个指向上一元素和下一元素的指针。所以它对插入、删除元素性能是最好的,而查询性能非常差;适合 大量地插入和删除操作而不关心随机存取的需求。
    deque 是介于两者之间,它兼顾了数组和链表的优点,它是分块的链表和多个数组的联合。所以它有被list 好的查询性能,有被vector 好的插入、删除性能。 如果你需要随即存取又关心两端数据的插入和删除,那么deque 是最佳之选。

3、关联容器的特点是明显的,相对于顺序容器,有以下几个主要特点:
A, 其内部实现是采用非线性的二叉树结构,具体的说是红黑树的结构原理实现的;
B, set 和map 保证了元素的唯一性,mulset 和mulmap 扩展了这一属性,可以允许元素不唯一;
C, 元素是有序的集合,默认在插入的时候按升序排列。

基于以上特点,
A, 关联容器对元素的插入和删除操作比vector 要快,因为vector 是顺序存储,而关联容器是链式存储;比list 要慢,是因为即使它们同是链式结构,但list 是线性的,而关联容器是二叉树结构,其改变一个元素涉及到其它元素的变动比list 要多,并且它是排序的,每次插入和删除都需要对元素重新排序;

B, 关联容器对元素的检索操作比vector 慢,但是比list 要快很多。vector 是顺序的连续存储,当然是比不上的,但相对链式的list 要快很多是因为list 是逐个搜索,它搜索的时间是跟容器的大小成正比,而关联容器 查找的复杂度基本是Log(N) ,比如如果有1000 个记录,最多查找10 次,1,000,000 个记录,最多查找20 次。容器越大,关联容器相对list 的优越性就越能体现;

C, 在使用上set 区别于vector,deque,list 的最大特点就是set 是内部排序的,这在查询上虽然逊色于vector ,但是却大大的强于list 。

D, 在使用上map 的功能是不可取代的,它保存了“键- 值”关系的数据,而这种键值关系采用了类数组的方式。数组是用数字类型的下标来索引元素的位置,而map 是用字符型关键字来索引元素的位置。在使用上map 也提供了一种类数组操作的方式,即它可以通过下标来检索数据,这是其他容器做不到的,当然也包括set 。(STL 中只有vector 和map 可以通过类数组的方式操作元素,即如同ele[1] 方式)。

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

C++ STL中各容器内存、优劣的分析 的相关文章

  • 在带有或不带有命名空间的 中使用类型

    在 C 11 中 我可以选择是否要使用带或不带命名空间 std 中定义的类型 至少我的编译器 g 4 7 接受这两种变体 我的问题是 使用 cstdint 中的 typedef 的推荐方法是什么 有或没有命名空间 有什么优点或缺点 或者这只
  • 在没有缓冲区的情况下将数据从 fstream 复制到 stringstream?

    无论如何 我可以从fstream 一个文件 到一个stringstream 内存中的流 目前 我正在使用缓冲区 但这需要双倍的内存 因为您需要将数据复制到缓冲区 然后将缓冲区复制到字符串流 直到删除缓冲区为止 数据都会在内存中复制 std
  • 有没有办法使用 Cereal / C++ 为 std::map 指定更简单的 JSON(反)序列化?

    我正在从事的项目是一个管理大量自定义硬件设备的 C 应用程序 该应用程序有一个供客户端使用的套接字 端口接口 如 GUI 每种设备类型都有自己定义良好的 JSON 模式 我们可以使用 Cereal 来序列化这些模式 但应用程序还需要解析来自
  • 哪个STL容器?

    我需要一个容器 不一定是 STL 容器 它可以让我轻松执行以下操作 在任意位置插入和移除元素 通过索引访问元素 以任意顺序迭代元素 I used 标准 列表 但它不会让我在任何位置插入 确实如此 但为此我必须迭代所有元素 然后在我想要的位置
  • 从函数返回 STL 向量 - 复制成本

    当您从函数返回 stl 向量时 vector
  • C++ 中模板和 STL 的缺点 [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 使用 STL 或模板有什么缺点吗 是否存在不适合的情况 首先 如果它们可以帮助您解决问题 您应该使用它们 模板是 C 非常重要的一部分 并且多年
  • 无法在向量向量上使用 emplace_back() 花括号初始化器

    这与我之前提出的有关使用的问题有些相关emplace back在对向量上 将一对插入到 std vector 时 emplace back 与 Push back https stackoverflow com questions 5390
  • Microsoft 的 STL::list::sort() 使用哪种排序算法?

    注 我不小心发帖了这个问题 https stackoverflow com questions 1717773 which sorting algorithm is used by stls listsort没有指定我正在使用哪个STL实现
  • 从 std::list 中删除具有特定值的元素

    我需要从 std list 中删除具有特定值的元素 随着list
  • C++ STL 下一个排列与组合

    我知道我可以使用std next permutation在包含元素的某些容器上 1 2 3 这将生成该序列的 6 种排列 我想做的是给定一些设置 1 2 3 4 5 6 生成大小为 3 的所有可能的排列 因此对于这个例子 4 3 2 将是由
  • 迭代 C++ 映射中的键

    有没有办法迭代键 而不是 C 映射对 地图是关联容器 因此 迭代器是一对key val 如果您只需要键 则可以忽略该对中的值部分 for std map
  • 如何找到向量中第一个小于整数 X 的元素? (c++)

    如果我有以下向量 10 10 10 20 20 20 30 30 我想要一个函数返回 X 的整数的位置或直接返回 X 之后的较小元素 例如如果我正在搜索 11 我希望函数返回 2 因为第二个元素 10 是第一个较小的元素向量中大于 11 的
  • 在 C++ 中将惰性生成器实现为forward_iterator

    MyGenerator 表示 可能 有限的整数序列 计算成本很高 所以我不想预先生成它们并将它们放入容器中 struct MyGenerator bool HasNext int Next 要打印全部 MyGenerator generat
  • 如何在 g++ 中使用不同的 STL

    我想对 g 使用不同的 STL 而不是其默认的 libstdc 做到这一点最简单的方法是什么 我发现 nostdinc 标志禁止 g 查找其 STL 标头 但这只是编译时的事情 它仍然会使 g 链接到它自己的 STL 所以我需要找到一种方法
  • 引用计数指针的STL类?

    这应该是微不足道的 但我似乎找不到它 除非不存在这样的类 智能指针的 STL 类 或类集 是什么 UPDATE 感谢您的回复 我必须说我很惊讶没有标准实施 我最终使用了这个 http archive gamedev net referenc
  • 如何从 wfstream 读取二进制数据?

    我从文件读取数据时遇到一个小问题 我希望能够读取 wstring 以及任意大小的原始数据块 大小以字节为单位 std wfstream stream file c str std wstring comType stream gt gt c
  • STL(标准模板库)中使用的设计模式

    我正在学习STL和设计模式 我想知道是否有任何文档或链接可以解释如何在 STL 中实现设计模式 我做了谷歌但无法获得太多数据 我希望你的意思是 哪些设计模式可以在STL中识别 STL 堆栈是一个容器适配器 适配器是一种设计模式 迭代器也是一
  • 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 的类型别名
  • 可能的 std::async 实现错误 Windows

    看来 std async 的 Windows 实现存在错误 在重负载下 大约每秒启动 1000 个异步线程 异步任务永远不会被调度 并且等待返回的 future 会导致死锁 请参阅这段代码 使用延迟启动策略而不是异步进行修改 Bundlin
  • 为什么 std::allocator 在 C++17 中丢失成员类型/函数?

    一边看着std 分配器 http en cppreference com w cpp memory allocator 我看到成员 value type pointer const pointer reference const refer

随机推荐

  • WIN7+Visual Studio 2013安装配置教程

    WIN7 43 Visual Studio 2013安装配置 本文将介绍如何在win7上安装Visual Studio 2013 一 xff1a 安装过程 1 下载Visual Studio 2013 安装包 下载之后的文件是 iso 格式
  • Ubuntu18.04 + Orb-Slam3 + USB双目摄像头

    Ubuntu18 04 43 Orb slam3 43 USB双目摄像头 本文将介绍如何在Ubuntu18 04上使用USB双目摄像头实现Orb slam3 主要硬件 我们以USB双目摄像头在Ubuntu18 04上来实现功能 xff1a
  • 树莓派结合Pixhawk飞控实现四轴双目视觉避障

    无人机双目视觉避障的实现 本文将介绍如何使用树莓派结合PIX飞控实现无人机双目视觉避障的功能 主要硬件 我们以双目摄像头 43 树莓派 43 Pixhawk飞控来实现功能 xff1a 双目摄像头与树莓派通过USB接口来连接 xff0c 树莓
  • TypeScript 终极初学者指南

    大家好 xff0c 我是 ConardLi xff0c 在过去的几年里 TypeScript 变得越来越流行 xff0c 现在许多工作都要求开发人员了解 TypeScript xff0c 各大厂的大型项目基本都要求使用 TypeScript
  • STM32——STM32库结构详解

    STM32库是由ST公司针对STM32提供的函数接口 xff0c 即API xff08 application program interface xff09 xff0c 开发者可以调用这些函数接口来配置STM32的寄存器 xff0c 脱离
  • 监控树莓派Raspberry Pi的CPU/GPU的温度

    监控树莓派Raspberry Pi的CPU GPU的温度 树莓派Raspberry Pi的CPU GPU的温度对于Pi的温度 高效运行非常重要 xff0c 所以我们要实时监控树莓派Raspberry Pi的CPU GPU的温度 1 运行环境
  • 【嵌入式系统】二、初识 Tiva TM4C123G系列开发板

    大二电赛小白 思考 主要偏向于嵌入式的应用 xff0c 请大家多多指教 xff01 TM4C123x系列是TI公司推出的一款32位基于ARM Cortex M4的处理器 1 TM4C123GH6PM的M4内核 超低功耗 耗电量370 A M
  • fdisk用法

    NAME fdisk Partition table manipulator for Linux SYNOPSIS fdisk u b sectorsize C cyls H heads S sects device fdisk l u d
  • 用策略模式优化代码的实例

    实例一 xff1a 利用利用策略模式实际开发中 if else 条件判断过多的问题 xff0c 条件少还好 xff0c 一旦 else if 过多这里的逻辑将会比较混乱 xff0c 并很容易出错 比如 xff1a 刚开始条件较少 xff0c
  • 灰度处理与二值化的关系

    当开始接触图像处理的童鞋可能跟我一样对这两个概念迷惑过 xff0c 在图像处理中 xff0c 用RGB三个分量 xff08 R xff1a Red xff0c G xff1a Green xff0c B xff1a Blue xff09 x
  • ucos2历程——信号量集

    信号量集 信号量集由两部分组成 xff1a 标识组和等待任务列表 xff1b 标识组由三部分组成 xff1a 1 OSFlagType 识别是否为信号量集的标志 2 OSFlagWaitList 指向等待任务列表的指针 3 OSFlagFl
  • 人体姿态估计资源大列表(Human Pose Estimation)

    基础 xff1a Human Pose Estimation人体姿态估计综述调研人体姿态估计数据集整理 xff08 Pose Estimation Keypoint xff09 姿态估计的两个数据集COCO和MPII的认识 Human Po
  • DIY小四轴之电路设计(一)

    DIY小四轴之电路设计 xff08 一 xff09 写在前面 前一阵时间一直在做四轴飞行器 xff0c 略有一点收获吧 xff0c 在这里分享出来 xff0c 一方面算是对自己的总结 xff0c 另一方面希望能给想做小四轴的读者一些思路 本
  • DIY小四轴之电路设计(二)

    DIY小四轴之电路设计 xff08 二 xff09 上次我分析了四轴电源的电路 xff0c 这次我们来看电机驱动与传感器电路 三 空心杯电机驱动电路 一般的小型四轴都选用空心杯电机来驱动旋翼 xff0c 空心杯电机不仅节能而且灵敏 xff0
  • ubuntu 18.04 vnc server开机自启动

    转自 xff1a https blog csdn net lixiaotao 1 article details 90140979 1 首先确定vncserver 以正确安装到linux系统 xff1b 2 设置vncserver随系统自启
  • vnc viewer灰屏的解决方法

    vnc能够连接上 xff0c 但是进入界面灰屏 先关闭当前打开的vnc xff1a vncserver kill 88 然后修改权限 xff1a chmod 43 x vnc xstartup 然后重新打开vnc vncserver geo
  • samba 常用命令

    没怎么修改配置 xff0c 但有时需要修改时 xff0c 又是搜索一番 xff0c 故将常用的在此备份一下 修改samba配置 xff1a span class token function sudo span span class tok
  • .rst 语法+简明教程

    reStructuredText 是扩展名为 rst的纯文本文件 xff0c 含义为 34 重新构建的文本 34 xff0c 也被简称为 xff1a RST或reST xff1b 是Python编程语言的Docutils项目的一部分 xff
  • TG_7100b准备开发环境

    请在 64 位 Ubuntu 下搭建开发环境 Win10 系统可以在应用商店下载安装 Ubuntu18 04 LTS 其他用户可以安装虚拟机软件 以下为基于 Ubuntu 环境开发和编译 SDK 时需要用到的库和依赖包 xff0c 请您按顺
  • C++ STL中各容器内存、优劣的分析

    STL有三大核心部分 xff1a 容器 xff08 Container xff09 算法 xff08 Algorithms xff09 迭代器 xff08 Iterator xff09 以下介绍容器相关内容 xff1a 各种容器的元素在内存