STL中各类容器详细介绍

STL介绍

STL(Standard Template Library),即标准模板库,是一个具有工业强度的,高效的C++程序库。它被容纳于C++标准程序库(C++ Standard Library)中,是ANSI/ISO C++标准中最新的也是极具革命性的一部分。该库包含了诸多在计算机科学领域里所常用的基本数据结构和基本算法。为广大C++程序员们提供了一个可扩展的应用框架,高度体现了软件的可复用性。

C++STL提供的数据结构

1. Sequence Containers:维持顺序的容器。

(a). vector:

动态数组,在堆中分配内存,是我们最常使用的数据结构之一。

特点:

  • 底层结构 : 底层由 动态数组 实现 , 特点是 存储空间 连续 ;
  • 访问遍历 : 支持 随机访问迭代器 , 可使用下标访问 , 访问元素非常快 O(1) 复杂度 ;
  • 插入 / 删除 : 尾部插入 / 删除效率高 O(1) 复杂度 ; 中间 和 头部插入/删除效率低 , 由于存储空间连续 , 需要将插入 / 删除位置之后的元素依次改变位置 , O(n) 复杂度 ;
  • 空间效率 : 底层实现时 , 会事先预留一些额外空间 , 以减少重新分配的次数 ;
  • 使用场景 : 需要 随机访问 且 频繁在尾部进行操作 的场景 ; 如果频繁增删元素 则 不适用该容器 ;

时间复杂度:

实现原理:

简单理解,就是vector是利用上述三个指针来表示的,基本示意图如下:
在这里插入图片描述
两个关键大小:
大小:size=_Mylast - _Myfirst;
容量:capacity=_Myend - _Myfirst;
分别对应于resize()、reserve()两个函数。


size表示vector中已有元素的个数,capacity表示vector最多可存储的元素的个数;

为了降低二次分配时的成本,vector实际配置的内存空间大小会比客户需求的更大一些,以备将来扩充,这就是capacity的概念。即capacity>=size,当等于时,容器此时已满,若再要加入新的元素时,就要重新进行内存分配,整个vector的数据都要移动到新内存。

vector:扩容机制:

vector 容器扩容的过程需要经历以下 3 步:

1. 完全弃用现有的内存空间,重新申请更大的内存空间;

2. 将旧内存空间中的数据,按原有顺序移动到新的内存空间中;

3. 最后将旧的内存空间释放。

因为 vector 扩容需要申请新的空间,所以扩容以后它的内存地址会发生改变。vector 扩容是非常耗时的,为了降低再次分配内存空间时的成本,每次扩容时 vector 都会申请比用户需求量更多的内存空间(这也就是 vector 容量的由来,即 capacity>=size),以便后期使用。VS里面扩容机制是1.5倍扩容,gcc里面是2倍扩容。


(b). list:

双向链表,也可以当作 stack 和 queue 来使用。有个缺点,链表不支持快速随机读取。

特点

  • 底层结构 : 底层由 双向链表 实现 , 特点是 存储空间 不连续 ;
  • 访问遍历 : 不支持 随机访问迭代器 , 只能通过迭代器进行访问 ;
  • 插入 / 删除 : 任意位置 插入 / 删除 效率都很高 ;
  • 空间效率 : 每个元素 都需要 分配额外的空间 , 存储 当前元素的 前驱元素 和 后继元素 ;
  • 使用场景 : 需要 在任意位置 频繁 插入 / 删除 操作的 场景 ;

时间复杂度:


(c). deque:

双端队列, 是一种优化了的、对序列两端元素进行添加和删除操作的基本序列容器。它允许较为快速地随机访问,但它不像vector 把所有的对象保存在一块连续的内存块,而是采用多个连续的存储块,并且在一个映射结构中保存对这些块及其顺序的跟踪。向deque 两端添加或删除元素的开销很小。它不需要重新分配空间,所以在两端端增删元素比vector 更有效。

特点:

  • 底层结构 : 底层由 双向队列 实现 , 特点是 存储空间 连续 ;
  • 访问遍历 : 支持 随机访问迭代器 , 其性能比 vector 动态素组要低 ;
  • 插入 / 删除 : 头部 和 尾部 插入 / 删除效率高 , O(1) 复杂度 ; 中间 插入/删除效率低 , 由于存储空间连续 , 需要将插入 / 删除位置之后的元素依次改变位置 , 比 vector 动态数组要快一些 ;
  • 空间效率 : 底层实现时比 vector 的结构要复杂 , 也会事先预留一些额外空间 , 以减少重新分配的次数 ;
  • 使用场景 : 需要 随机访问 且 频繁在 首部 和 尾部 进行操作 的场景 ; 如果频繁 在中部 增删元素 则 不适用该容器 ;

实现原理:

deque 是由一段一段的定量的连续空间构成。一旦有必要在 deque 前端或者尾端增加新的空间,便配置一段连续定量的空间,串接在 deque 的头端或者尾端。deque 最大的工作就是维护这些分段连续的内存空间的整体性的假象,并提供随机存取的接口,避开了重新配置空间,复制,释放的轮回,代价就是复杂的迭代器架构。
既然 deque 是分段连续内存空间,那么就必须有中央控制,维持整体连续的假象,数据结构的设计及迭代器的前进后退操作颇为繁琐。

deque 采取一块所谓的 map(不是 STL 的 map 容器)作为主控,这里所谓的 map 是一小块连续的内存空间,其中每一个元素(此处成为一个结点)都是一个指针,指向另一段连续性内存空间,称作缓冲区。缓冲区才是 deque的存储空间的主体。

时间复杂度:


(d). array:

固定大小的数组,一般在刷题时我们不使用。


(e). forward_list:

单向链表,一般在刷题时我们不使用。


2. Container Adaptors:基于其它容器实现的数据结构。

(a). stack:

后入先出(LIFO)的数据结构,默认基于 deque 实现。stack 常用于深度优先搜
索、一些字符串匹配问题以及单调栈问题。


(b). queue:

先入先出(FIFO)的数据结构,默认基于 deque 实现。queue 常用于广度优先
搜索。


(c). priority_queue:

最大值先出的数据结构,默认基于vector实现堆结构。它可以在O(n log n)
的时间排序数组,O(log n) 的时间插入任意值,O(1) 的时间获得最大值,O(log n) 的时
间删除最大值。priority_queue 常用于维护数据结构并快速获取最大或最小值。


3. Associative Containers:实现了排好序的数据结构。

(a). set:

有序集合,元素不可重复,底层实现默认为红黑树,它可以在 O(n log n) 的时间排序数组,O(log n) 的时间插入、删除、查找任何节点。这里注意,set 和 priority_queue 都可以用
于维护数据结构并快速获取最大最小值,但是它们的时间复杂度和功能略有区别,如
priority_queue 默认不支持删除任意值,而 set 获得最大或最小值的时间复杂度略高,具
体使用哪个根据需求而定。

特点:

  • 底层结构 : 底层由 红黑树 实现 , 红黑树 是 一种 平衡二叉搜索树 , 存储空间 不连续 ;
  • 访问遍历 : 不支持 随机访问迭代器 , 不能通过过下标访问 , 只能通过迭代器进行访问 ;
  • 插入 / 删除 : 查询 / 插入 / 删除 效率 为 O(log n) 复杂度 ;
  • 排序方式 : 默认使用 less 仿函数 , 即 < 运算符进行排序 ; 也可以自定义 排序规则 仿函数 ;
  • 使用场景 : 需要 有序集合 且 元素 不重复 的场景 ;

时间复杂度:

增删改查都近似 = O(log N)


(b). multiset:

支持重复元素的 set。

(c). map:

有序映射或有序表,在 set 的基础上加上映射关系,可以对每个元素 key 存一个
值 value。

特点:

  • 底层结构 : 底层由 红黑树 实现 , 红黑树 是 一种 平衡二叉搜索树 , 存储空间 不连续 ; 存储的 元素 是 键值对 元素 ;
  • 访问遍历 : 不支持 随机访问迭代器 , 不能听过下标访问 , 只能通过迭代器进行访问 ;
  • 插入 / 删除 : 查询 / 插入 / 删除 效率 为 O(log n) 复杂度 ; 与 set 集合容器相同 ;
  • 排序方式 : 默认使用 less 仿函数 , 即 < 运算符进行排序 ; 也可以自定义 排序规则 仿函数 ; map 映射容器 不允许重复的键 , multimap 多重映射容器允许重复的键 ;
  • 使用场景 : 需要 有序 键值对 且 元素 不重复 的场景 ;
std::map 映射容器 与 std::set 集合容器 的区别是
map 容器存储的是 键值对 元素 , 元素是 pair  
set 容器 存储的是 单纯的 键 单个元素 ;

时间复杂度:

增删改查都近似 = O(log N)


(d). multimap:

支持重复元素的 map。


4. Unordered Associative Containers:对每个 Associative Containers 实现了哈希版本。

(a). unordered_set:

哈希集合,可以在 O(1) 的时间快速插入、查找、删除元素,常用于快
速的查询一个元素是否在这个容器内。


(b). unordered_multiset:

支持重复元素的 unordered_set。


(c). unordered_map:

哈希映射或哈希表,在 unordered_set 的基础上加上映射关系,可以对
每一个元素 key 存一个值 value。在某些情况下,如果 key 的范围已知且较小,我们也
可以用 vector 代替 unordered_map,用位置表示 key,用每个位置的值表示 value。


(d). unordered_multimap:

支持重复元素的 unordered_map。

STL 各容器使用场景示例

  • 如果需要 随机访问 , 则使用 vector 单端数组 或 deque 双端数组 容器 ;
  • 如果 需要 在 尾部 频繁 插入 / 删除 , 则使用 vector 单端数组 ;
  • 如果 需要 在 首部 和 尾部 频繁 插入 / 删除 , 则使用 deque 双端数组 ;
  • 如果 需要 在 任意位置 频繁 插入 / 删除 , 则使用 list 双向链表 ;
  • 如果需要保持 元素 有序 且 不重复 , 则使用 set 集合容器 ;
  • 如果需要保持 元素 有序 且 可重复 , 则使用 multiset 多重集合容器 ;
  • 如果不需要保持 元素 有序 , 可使用unordered_set, unordered_map;


————————————————
引用:

https://blog.csdn.net/zuihaobizui/article/details/119741156

https://blog.csdn.net/shulianghan/article/details/135363350

https://www.cnblogs.com/yinbiao/p/11636405.html

C++ vector的内部实现原理及基本用法_vector内部实现-CSDN博客

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

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

相关文章

tsv、csv、xls等文件类型区别及处理(python版)

目录 前言 介绍 tsv、csv、txt的区别 读取/生成 不同格式数据文件&#xff08;python&#xff09; 一、读取/生成csv数据文件 二、读取/生成txt数据文件 三、读取/生成tsv数据文件 四、读取/生成xls数据文件 不同文件格式转化 总结 前言 考虑到进行机器学习、深度学习…

代码随想录day35--动态规划的应用2||01背包理论基础、携带研究材料

01背包理论基础 有n件物品和一个最多能背重量为w的背包。第i件物品的重量是weight[i],得到的价值为 value[i]。每件物品只能用一次&#xff0c;将这些物品装入背包里物品价值总和最大。 这是很标准的背包问题&#xff0c;很多同学看到后很自然的就想到了背包&#xff0c;我们…

【Linux学习】Linux 的虚拟化和容器化技术

˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如…

少儿编程 2024年3月电子学会图形化编程等级考试Scratch一级真题解析(选择题)

2024年3月scratch编程等级考试一级真题 选择题&#xff08;共25题&#xff0c;每题2分&#xff0c;共50分&#xff09; 1、单击下列哪个按钮&#xff0c;能够让舞台变为“全屏模式” A、 B、 C、 D、 答案&#xff1a;C 考点分析&#xff1a;考查scratch平台的使用&…

java中Date类,SimpleDateFormat类和Calendar类

Date类 public Date() 创建一个Date对象&#xff0c;代表的是系统当前此刻的日期时间 public Date(long date) Constructs a Date object using the given milliseconds time value. 把时间毫秒值转变成Date日期对象 public void setTime(long date) Sets an existing Date ob…

【爬虫开发】爬虫从0到1全知识md笔记第3篇:数据提取概要,知识点【附代码文档】

爬虫开发从0到1全知识教程完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;爬虫课程概要&#xff0c;爬虫基础爬虫概述,,http协议复习。requests模块&#xff0c;requests模块1. requests模块介绍,2. response响应对象,3. requests模块发送请求,4. request…

接口练习题目

练习一 1、声明接口Eatable&#xff0c;包含抽象方法public abstract void eat(); 2、声明实现类中国人Chinese&#xff0c;重写抽象方法&#xff0c;打印用筷子吃饭 3、声明实现类美国人American&#xff0c;重写抽象方法&#xff0c;打印用刀叉吃饭 4、声明实现类印度人Indi…

深入Tauri开发——从环境搭建到项目构建

深入Tauri开发——从环境搭建到项目构建 开启你的Tauri桌面应用开发之旅&#xff08;续&#xff09; 经过上一篇文章的基础介绍&#xff0c;现在让我们更进一步&#xff0c;详细阐述如何在Windows和macOS平台上顺利搭建Tauri应用所需的开发环境&#xff0c;并指导您从创建项目…

Python搭建编程环境-安装Python3解释器

✅作者简介&#xff1a;CSDN内容合伙人、新星计划第三季Python赛道Top1&#x1f3c5; &#x1f525;本文已收录于Python系列专栏&#xff1a;零基础学Python &#x1f4ac;订阅专栏后可私信博主进入Python学习交流群&#xff0c;进群可领取Python视频教程以及Python相关电子书…

数据结构——图的应用(最小生成树,最短路径,拓扑排序,关键路径)

目录 1.最小生成树 1.概念回顾——生成树 2.最小生成树概念 2.构造最小生成树 1.MST性质 2.Prim算法 3.Kruskal 算法 4.两种算法比较 3.最短路径 1.两点间最短路径 2.某源点到其它各点最短路径 3.单源最短路径——用Dijkstra算法 4.所有顶点间的最短路径…

算法沉淀——动态规划篇(子数组系列问题(下))

算法沉淀——动态规划篇&#xff08;子数组系列问题&#xff08;下&#xff09;&#xff09; 前言一、等差数列划分二、最长湍流子数组三、单词拆分四、环绕字符串中唯一的子字符串 前言 几乎所有的动态规划问题大致可分为以下5个步骤&#xff0c;后续所有问题分析都将基于此 …

NoSQL之Redis

目录 一、关系型数据库与非关系型数据库 1.关系数据库 2.非关系数据库 2.1非关系型数据库产生背景 3.关系型数据库与非关系型数据区别 &#xff08;1&#xff09;数据存储方式不同 &#xff08;2&#xff09;扩展方式不同 &#xff08;3&#xff09;对事物性的支持不同 …

瑞吉外卖实战学习--14、菜品上传

添加菜品接口 前言效果图1、菜品分类查询接口2、上传图片和下载图片3、创建接收数据的Dto4、创建提交的方法 前言 本项目gitee位置&#xff1a;gitee网址 本篇文章是学习了添加菜品的总结&#xff0c;其中包括菜品分类的接口&#xff0c;图片上传接口&#xff0c;数据整体上传…

Java源值1.5已过时,将在未来所有发行版中删除

1、背景 确认java项目没问题&#xff0c;但是启动的时候&#xff0c;却报错&#xff1a;java: -source 1.5 中不支持 diamond 运算符 2、解决 2.1 2.2 2.3 2.4 2.5

python 插值搜索-迭代与递归(Interpolation Search)

给定一个由 n 个均匀分布值 arr[] 组成的排序数组&#xff0c;编写一个函数来搜索数组中的特定元素 x。 线性搜索需要 O(n) 时间找到元素&#xff0c;跳转搜索需要 O(? n) 时间&#xff0c;二分搜索需要 O(log n) 时间。 插值搜索是对实例二分搜索的改进&#xff0c;…

一致性hash问题(负载均衡原理)

一致性哈希问题 简介 一致性Hash是一种特殊的Hash算法&#xff0c;由于其均衡性、持久性的映射特点&#xff0c;被广泛的应用于负载均衡领域&#xff0c;如nginx和memcached都采用了一致性Hash来作为集群负载均衡的方案。 本文将介绍一致性Hash的基本思路&#xff0c;并讨论其…

程序代码分析工具

文章目录 工具简介和安装DoxygenGraphziv软件安装 工具的运用启动和配置工具分析结果 工具简介和安装 Doxygen Doxygen 是一种用于从 C 、C 、Objective-C 、C# 、Java 和 Python 等语言的源代码中生成文档的工具。它通过解析源代码中的注释来创建详细的 API 文档&#xff0c;…

蓝桥杯23年第十四届省赛-异或和之和|拆位、贡献法

题目链接&#xff1a; 蓝桥杯2023年第十四届省赛真题-异或和之和 - C语言网 (dotcpp.com) 1.异或和之和 - 蓝桥云课 (lanqiao.cn) 参考题解&#xff1a; 蓝桥杯真题讲解&#xff1a;异或和之和 &#xff08;拆位、贡献法&#xff09;-CSDN博客 洛谷P9236 [蓝桥杯 2023 省 A]…

STM32中启用 UART 的特定中断( __HAL_UART_ENABLE_IT函数)开机立即进入中断问题(HAL库)

学习过程中发现启用 UART 的特定中断功能之后&#xff0c;原本应该是等到空闲中断的标志位变化了再进入中断&#xff0c;结果MCU开机就会进入中断&#xff0c;不符合逻辑&#xff0c;所以尝试解决这个问题。 DMA空闲中断 处理 串口接收不定长数据 的文章见以下 原文链接&#…

harmonyOS安装ohpm

下载 下载地址 HUAWEI DevEco Studio和SDK下载和升级 | 华为开发者联盟 初始化 注意&#xff1a;初始化ohpm前&#xff0c;需先完成node.js环境变量配置 1.解压文件&#xff0c;进入commandline-tools-windows-2.0.0.2\command-line-tools\ohpm\bin 2.执行&#xff1a; init.ba…