掌握C++11标准库(STL):理解STL的核心概念

深入探索C++11标准库STL:新特性和优化技巧

  • 一、前言
  • 二、容器简介
  • 三、迭代器简介
  • 四、map与unordered_map(红黑树VS哈希表)
    • 4.1、map和unordered_map的差别
    • 4.2、优缺点以及适用处
    • 4.3、小结
  • 五、总结

一、前言

STL定义了强大的、基于模板的、可复用的组件,实现了许多通用的数据结构及处理这些数据结构的算法。其中包含三个关键组件——容器(container,流行的模板数据结构)、迭代器(iterator)和算法(algorithm)。

组件描述
容器容器是用来管理某一类对象的集合。C++ 提供了各种不同类型的容器,比如 deque、list、vector、map 等。
迭代器用于遍历对象集合的元素。这些集合可能是容器,也可能是容器的子集。
算法算法作用于容器。它们提供了执行各种操作的方式,包括对容器内容执行初始化、排序、搜索和转换等操作。

二、容器简介

STL容器,可将其分为四类:序列容器、有序关联容器、无序关联容器、容器适配器。

序列容器:

标准库容器类描述
array固定大小,直接访问任意元素
deque从前部或后部进行快速插入和删除操作,直接访问任何元素
forward_list单链表,在任意位置快速插入和删除
list双向链表,在任意位置进行快速插入和删除操作
vector从后部进行快速插入和删除操作,直接访问任意元素
Sequence Containers
vector
list
deque
array
forward_list

有序关联容器(键按顺序保存):

标准库容器类描述
set快速查找,无重复元素
multiset快速查找,可有重复元素
map一对一映射,无重复元素,基于键快速查找
multimap一对一映射,可有重复元素,基于键快速查找
Associative Containers
Set
Map
Multiset
Multimap

无序关联容器:

标准库容器类描述
unordered_set快速查找,无重复元素
unordered_multiset快速查找,可有重复元素
unordered_map一对一映射,无重复元素,基于键快速查找
unordered_multimap一对一映射,可有重复元素,基于键快速查找
Unordered Containers
Unordered_set
Unordered_map
Unordered_multiset
Unordered_multimap

容器适配器:

标准库容器类描述
stack后进先出(LIFO)
queue先进先出(FIFO)
priority_queue优先级最高的元素先出

序列容器描述了线性的数据结构(也就是说,其中的元素在概念上” 排成一行"), 例如数组、向量和 链表。

关联容器描述非线性的容器,它们通常可以快速锁定其中的元素。这种容器可以存储值的集合或 者键-值对。

栈和队列都是在序列容器的基础上加以约束条件得到的,因此STL把stack和queue作为容器适配器来实现,这样就可以使程序以一种约束方式来处理线性容器。类型string支持的功能跟线性容器一样, 但是它只能存储字符数据。

三、迭代器简介

迭代器在很多方面与指针类似,也是用于指向首类容器中的元素(还有一些其他用途,后面将会提
到)。 迭代器存有它们所指的特定容器的状态信息,即迭代器对每种类型的容器都有一个实现。 有些迭代器的操作在不同容器间是统一的。 例如,运算符间接引用一个迭代器,这样就可以使用它所指向的元素。++运算符使得迭代器指向容器中的下一个元素(和数组中指针递增后指向数组的下一个元素类似)。

STL 首类容器提供了成员函数begin end。函数 begin 返回一个指向容器中第一个元素的迭代器,函数 end 返回一个指向容器中最后一个元素的下一个元素(这个元素并不存在,常用于判断是否到达了容器的结束位位置)的迭代器。 如果迭代器 it 指向一个特定的元素,那么 ++it 指向这个元素的下一个元素。*it 指代的是it指向的元素。 从函数 end 中返回的迭代器只在相等或不等的比较中使用,来判断这个“移动的迭代器” (在这里指it)是否到达了容器的末端。

使用一个 iterator 对象来指向一个可以修改的容器元素,使用一个 const_iterator 对象来指向一个不能修改 的容器元素。

类型描述
随机访问迭代器(random access)在双向迭代器基础上增加了直接访问容器中任意元素的功能, 即可以向前或向后跳转任意个元素
双向迭代器(bidirectional)在前向迭代器基础上增加了向后移动的功能。支持多遍扫描算法
前向迭代器(forword)综合输入和输出迭代器的功能,并能保持它们在容器中的位置(作为状态信息),可以使用同一个迭代器两次遍历一个容器(称为多遍扫描算法)
输出迭代器(output)用于将元素写入容器。 输出迭代楛每次只能向前移动一个元索。 输出迭代器只支持一遍扫描算法,不能使用相同的输出迭代器两次遍历一个序列容器
输入迭代器(input)用于从容器读取元素。 输入迭代器每次只能向前移动一个元素。 输入迭代器只支持一遍扫描算法,不能使用相同的输入迭代器两次遍历一个序列容器

每种容器所支持的迭代器类型决定了这种容器是否可以在指定的 STL 算 法中使用。 支持随机访问迭代器的容器可用于所有的 STL 算法(除了那些需要改变容器大小的算法,这样的算法不能在数组和 array对象中使用)。 指向 数组的指针可以代替迭代器用于几乎所有的 STL 算法中,包括那些要求随机访问迭代器的算法。

Bidirectional Iterator
Random Access Iterator
Forward Iterator
Input Iterator
Output Iterator

下表显示了每种 STL 容器所支持的迭代器类型。 注意, vector 、 deque 、 list 、 set、 multiset 、 map 、 multimap以及 string 和数组都可以使用迭代器遍历。

容器支持的迭代器类型容器支持的迭代器类型
vector随机访问迭代器set双向迭代器
array随机访问迭代器multiset双向迭代器
deque随机访问迭代器map双向迭代器
list双向迭代器multimap双向迭代器
forword_list前向迭代器unordered_set双向迭代器
stack不支持迭代器unordered_multiset双向迭代器
queue不支持迭代器unordered_map双向迭代器
priority_queue不支持迭代器unordered_multimap双向迭代器

下表显示了在 STL容器的类定义中出现的几种预定义的迭代器 typedef。不是每种 typedef 都出现在每个容器中。 我们使用常量版本的迭代器来访问只读容器或不应该被更改的非只读容器,使用反向迭代器来以相反的方向访问容器。

为迭代器预先定义的typedef++的方向读写能力
iterator向前读/写
const_iterator向前
reverse_iterator向后读/写
const_reverse_iterator向后

下表显示了可作用在每种迭代器上的操作。 除了给出的对于所有迭代器都有的运算符,迭代器还必须提供默认构造函数、拷贝构造函数和拷贝赋值操作符。 前向迭代器支持++ 和所有的输入和输出迭代器的功能。 双向迭代器支持–操作和前向迭代器的功能。 随机访问迭代器支持所有在表中给出的操作。 另外, 对于输入迭代器和输出迭代器,不能在保存迭代器之后再使用保存的值。

适用所有迭代器的操作描述
++p前置自增迭代器
p++后置自增迭代器
p=p1将一个迭代器赋值给另一个迭代器
输入迭代器描述
*p间接引用一个迭代器
p->m使用迭代器读取元素m
p==p1比较两个迭代器是否相等
p!=p1比较两个迭代器是否不相等
输出迭代器描述
*p间接引用一个迭代器
p=p1把一个迭代器赋值给另一个

前向迭代器:前向迭代器提供了输入和输出迭代器的所有功能。

双向迭代器描述
–pq
p–后置自减迭代器
随机访问迭代器描述
p+=i迭代器p前进i个位置
p-=i迭代器p后退i个位置
p+i在迭代器p 的位置上前进i个位置
p-i在迭代器p的位置上后退i个位置
p-p1表达式的值是一个整数,它代表同一个容器中两个元素间的距离
p[i]返回与迭代器p的位置相距i的元素
p<p1若迭代器p小于p1(即容器中p在p1前)则返回 true, 否则返回 false
p<=p1若迭代器p小千或等于p1 (即容器中p 在p1前或位咒相同)则返回 true, 否则返回 false
p>p1若迭代器p 大于p1(即容器中p在p1后)则返回true, 否则返回false
p>=p1若迭代器p大于或等于p1(即容楛中p在p1后或位置相同)则返回 true, 否则返回 false

四、map与unordered_map(红黑树VS哈希表)

C++11 增加了无序容器 unordered_map/unordered_multimap 和unordered_set/unordered_multiset,由于这些容器中的元素是不排序的,因此,比有序容器map/multimap 和 set/multiset 效率更高。 map 和 set 内部是红黑树,在插入元素时会自动排序,而无序容器内部是散列表( Hash Table),通过哈希( Hash),而不是排序来快速操作元素,使得效率更高。由于无序容器内部是散列表,因此无序容器的 key 需要提供 hash_value 函数,其他用法和map/set 的用法是一样的。不过对于自定义的 key,需要提供 Hash 函数和比较函数。

4.1、map和unordered_map的差别

(1)需要引入的头文件不同。

  • map: #include <map>
  • unordered_map: #include <unordered_map>

(2)内部实现机理不同。

  • map: map内部实现了一个红黑树(红黑树是非严格平衡二叉搜索树,而AVL是严格平衡二叉搜
    索树),红黑树具有自动排序的功能,因此map内部的所有元素都是有序的,红黑树的每一个节点
    都代表着map的一个元素。
  • unordered_map: unordered_map内部实现了一个哈希表(也叫散列表,通过把关键码值映射到
    Hash表中一个位置来访问记录,查找的时间复杂度可达到O(1),其在海量数据处理中有着广泛应
    用)。因此,其元素的排列顺序是无序的。

4.2、优缺点以及适用处

map:

  1. 优点:有序性,这是map结构最大的优点,其元素的有序性在很多应用中都会简化很多的操作
    红黑树,内部实现一个红黑书使得map的很多操作在log n 的时间复杂度下就可以实现,因此效率非常的高。
  2. 缺点:空间占用率高,因为map内部实现了红黑树,虽然提高了运行效率,但是因为每一个节点都需要额外保存父节点、孩子节点和红/黑性质,使得每一个节点都占用大量的空间。
  3. 适用处:对于那些有顺序要求的问题,用map会更高效一些。

unordered_map:

  1. 优点: 因为内部实现了哈希表,因此其查找速度非常的快。
  2. 缺点: 哈希表的建立比较耗费时间。
  3. 适用处:对于查找问题,unordered_map会更加高效一些,因此遇到查找问题,常会考虑一下用unordered_map。

4.3、小结

  1. 内存占有率的问题就转化成红黑树 VS hash表 , 还是unorder_map占用的内存要高。
  2. 但是unordered_map执行效率要比map高很多。
  3. 对于unordered_map或unordered_set容器,其遍历顺序与创建该容器时输入的顺序不一定相同,因为遍历是按照哈希表从前往后依次遍历的。

五、总结

C++ 参考手册,重点学习C++11起的容器。
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

python设计模式:模板方法模式

更多Python学习内容&#xff1a;ipengtao.com 软件设计和编程中&#xff0c;设计模式是一种有助于解决常见问题的强大工具。其中之一是"模板方法模式"&#xff0c;它是一种行为型设计模式&#xff0c;允许你定义一个算法的骨架&#xff0c;但将一些步骤的具体实现延迟…

win11 电脑睡眠功能失效了如何修复 win11 禁止鼠标唤醒

1、win11睡眠不管用怎么办&#xff0c;win11电脑睡眠功能失效了如何修复 在win11系统中拥有许多令人激动的新功能和改进&#xff0c;有些用户在使用win11电脑时可能会遇到一个问题&#xff1a;睡眠模式不起作用。当他们尝试将计算机置于睡眠状态时&#xff0c;却发现系统无法进…

HarmonyOS应用程序包快速修复

快速修复概述 快速修复是HarmonyOS系统提供给开发者的一种技术手段&#xff0c;支持开发者以远快于应用升级的方式对应用程序包进行缺陷修复。和全量应用升级软件版本相比&#xff0c;快速修复的主要优势在小、快和用户体验好。在较短的时间内不中断正在运行的应用的情况下&am…

SpringBoot + Vue 抖音全平台项目

简介 本项目是一个短视频平台&#xff0c;拥有热度排行榜&#xff0c;热门视频&#xff0c;兴趣推送&#xff0c;关注推送&#xff0c;内容审核等功能。 源码下载 网盘 (访问密码: 8418) 登录/注册 首页 创作中心 架构设计 上传视频业务流程 视频推送流程 1.用户订阅分类后…

聚类:聚类的介绍及k-means算法

聚类&#xff1a;聚类的介绍及k-means算法 什么是聚类 聚类就是在输入为多个数据时&#xff0c;将“相似”的数据分为一组的操作。1 个组就叫作 1 个 “簇”。下面的示例中每个点都代表1 个数据&#xff0c;在平面上位置较为相近、被圈起来的点就代表一 类相似的数据。也就是…

如何为开源项目和社区做贡献 -- 你应该知道的十件事(一)

1. 前言 大家好&#xff0c;我叫颜国进&#xff0c;现为英特尔边缘计算创新大使、百度飞桨开发者专家。回溯至2021年12月&#xff0c;那时的我&#xff0c;身为机械专业研一新生&#xff0c;仅在C和Python编程语言上有些许基础&#xff0c;对于深度学习的殿堂还只敢在门口窥探&…

【动态规划】【字符串】C++算法:正则表达式匹配

作者推荐 视频算法专题 涉及知识点 动态规划 字符串 LeetCode10:正则表达式匹配 给你一个字符串 s 和一个字符规律 p&#xff0c;请你来实现一个支持 ‘.’ 和 ‘’ 的正则表达式匹配。 ‘.’ 匹配任意单个字符 ’ 匹配零个或多个前面的那一个元素 所谓匹配&#xff0c;是…

web网站的工作流程和开发模式

web网站的工作流程和开发模式 基于Java Script封装的高级技术&#xff1a;Vue、Element、Nginx(前端程序部署的服务器) 初识Web前端 Web标准

Conv2Former:一种transformer风格的卷积特征提取方式

一、前言 昨天读到了一篇有意思的文章&#xff0c;文章提出通过利用卷积调制操作来简化self-attention。还证明了这种简单的方法可以更好地利用卷积层中嵌套的大核(≥7 7)。我们都知道ViTs推动了设计识别模型的发展&#xff0c;近几年使用的也相当的多&#xff0c;通常就是CN…

《ORANGE’S:一个操作系统的实现》读书笔记(十九)输入输出系统(一)

我们刚刚实现了简单的进程&#xff0c;你现在可能很想把它做得更加完善&#xff0c;比如进一步改进调度算法、增加通信机制等。但是这些工作不但做起来没有尽头&#xff0c;而且有些也是难以实现的&#xff0c;因为进程必须与I/O、内存管理等其它模块一起工作。而且&#xff0c…

Linux系统---进程程序替换

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C/C》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、进程程序替换 一、替换原理 用fork 创建子进程后执行的是和父进程相同的程序 ( 但有可能执行不同的代码分支 ), 子进程往往要…

02 HAL库驱动按键响应外部中断

引言&#xff1a;这里我采用的实验平台可能跟大家的不太一样&#xff0c;文章的图像是一块资源拓展板&#xff0c; 主控板式fs_mp1a, 该板子的SOC是stm32mp157a&#xff0c; 有两个内核一个A7&#xff0c; 一个M4.但是实验的流程肯定都是一样的&#xff0c; 因为都是裸机程序嘛…

【PTA-C语言】实验七-函数与指针I

如果代码存在问题&#xff0c;麻烦大家指正 ~ ~有帮助麻烦点个赞 ~ ~ 目录——实验七-函数与指针I 6-1 弹球距离&#xff08;分数 10&#xff09;6-2 使用函数输出一个整数的逆序数&#xff08;分数 10&#xff09;6-3 使用函数求最大公约数&#xff08;分数 10&#xff09;6-4…

Visual Studio 2015 中 SDL2 开发环境的搭建

Visual Studio 2015 中 SDL2 开发环境的搭建 Visual Studio 2015 中 SDL2 开发环境的搭建新建控制台工程拷贝并配置 SDL2 开发文件拷贝 SDL2 开发文件配置 SDL2 开发文件 测试SDL2 开发文件的下载链接 Visual Studio 2015 中 SDL2 开发环境的搭建 新建控制台工程 新建 Win32 …

从2023看2024前端发展趋势

前言 流光溯影&#xff0c;纵观2023全年&#xff0c;整个前端业界呈现出百业凋零之状&#xff0c;更不乏有“前端已死”等论调甚嚣尘上。从全局视角看IT行业&#xff0c;除了AI领域的大语言模型爆发外&#xff0c;整体都鲜有特别亮眼及突出的技术展现。故而&#xff0c;作为IT…

【华为机试】2023年真题B卷(python)-猴子爬山

一、题目 题目描述&#xff1a; 一天一只顽猴想去从山脚爬到山顶&#xff0c;途中经过一个有个N个台阶的阶梯&#xff0c;但是这猴子有一个习惯&#xff1a; 每一次只能跳1步或跳3步&#xff0c;试问猴子通过这个阶梯有多少种不同的跳跃方式&#xff1f; 二、输入输出 输入描述…

深度学习核心技术与实践之计算机视觉篇

非书中全部内容&#xff0c;只是写了些自认为有收获的部分 计算机视觉背景 &#xff08;1&#xff09;视觉皮层的神经元是一列一列组织起来的&#xff0c;每一列神经元只喜欢某一种特定的形状或者某些简单的线条组合&#xff0c;而不是鱼、老鼠、鲜花 &#xff08;2&#xf…

记矩阵基础概念

转自up&#xff1a;Naruto_Qcsdn&#xff1a;三维空间几何变换矩阵 先贴个站里分享的基础概念。 learn form 肥猫同学VFX b站&#xff1a;会用transform就会用矩阵 移动 旋转 缩放 1.transofrm ——输出变化矩阵 可以移动transform查看变化去理解 位移 缩放 旋转 由此—…

一个有趣的MOSFET电路-触摸调光电路

来源 刷B站视频&#xff0c;看到一个很新奇的“触摸调光电路”&#xff0c;电路图如下&#xff1a; 视频在这里&#xff0c;只使用了3个元件。 刚好最近在学模拟电路的 MOSFET&#xff0c;我之前的理解是 MOSFET 的控制电压应该加在 Gate 和 Source 之间&#xff0c;也就是 栅…

【ES】es介绍,使用spring-boot-starter-data-elasticsearch整合的ES来进行操作Es

文章目录 倒排索引&#xff08;Inverted Index&#xff09;和正排索引&#xff08;Forward Index&#xff09;es和MySQL对比IK分词器的总结mapping映射使用springboot整合的ES来进行操作Es1. 实体类中添加注解2. 编写Repository层3. 通过Repository进行增删改查 倒排索引&#…