本文是一篇读书笔记,可以在偏向文字叙述方面让你了解STL,代码涉及到的不多,如果你明天面试,看看整个也许有点帮助,笔者就曾经被人问到:vector和list有什么区别?很遗憾当时我没有回答上来,现在的话似乎好一点了。他们都可以在尾部添加元素,vector是可以动态扩展的数组,list是链表,优势是在任何位置插入和删除元素都很快。而vector是在尾部添加数据比较快,在中间插入元素就很慢了。

STL(standard template library)是一个泛型程序库。从程序员的角度来看,STL是由一些可适应不同需求的集合类和一些能够在这些数据集合上运作的算法构成。STL内的所有组件都由template构成,所以其元素可以是任意类型。更妙的是STL建立了一个框架,在此框架下可以提供其他集合类或算法,与现有的组件搭配共同运作。

6.1STL组件

容器(Container):用来管理某类对象的集合。

迭代器(Iterator):用来对一个对象集合内遍历元素。迭代器的好处是为所有各式各样的容器提供了一组很小的共通接口。每一种容器都提供了自己的迭代器,而这些迭代器了解容器的内部结构,知道该做什么。

算法(Algorithm)用来处理集合内的元素。它们可以是查找、排序、修改、使用元素。

STL的基本观念就是将数据和操作分离。数据由容器来加以管理,操作由可定制的算法来定义。迭代器在两者之间充当粘合剂,使得任何算法都可以和任何容器交互运作。

6.2容器

先来看一张图,该图非常好,帮助我们记忆STL的容器。

下面的是一个表格,说明白了啥是啥。来源于大师BJARNE STROUSTRUP 的书籍《C++程序设计语言》。

STL 里面的各位大神都是干什么吃的?
<vector> 可变大小一维数组
<deque> 双端队列
<forward_list> 单向列表
<list> 双向列表
<map> 关联数组
<set> 集合
<unordered_map> 哈希关联数组
<unordered_set> 哈希集合
<queue> 队列
<stack>
<array> 固定大小一维数组
<bitset> bool数组

上面的表格背景颜色也有含义,同色的是属于同一个种类的。请牢记上面的表格。

容器可以分为三大类:

序列式容器(Sequence container):这是一种有序(ordered)集合(这个有序是order是由顺序的意思,不是大小的比较,那个的英文是sorted),每个元素均有确凿的位置--取决于插入时机和地点,与元素值无关。如果你以追加方式对一个集合置入6个元素,他们的排列次序和置入次序是一致的。五个序列式容器:array、vector、deque、list、forward_list。序列式容器(Sequence container)通常被实现为array或linked list。

关联式容器(Associative container):这是一种已排序(sorted)集合,元素的位置取决于其value(或key 如果元素是个key /value pair)和某种排序规则。四个关联式容器:set、multiset、map、multimap。关联式容器(Associative container)通常被实现为binary tree。

无序容器(Unordered(associative) container):这是一种无序集合,其内每个元素的位置无关紧要,唯一重要的是某特定元素是否位于集合内。元素值或者安插的顺序都不影响元素的位置,而且元素的位置有可能在容器生命周期内发生改变。由四个无序容器:unordered_set、unordered_multiset、unordered_map、unordered_multimap。(实在是其不出来新的名字了,干脆都加个unordered_得啦。)无序容器(Unordered(associative) container)通常被实现为hash table。

关联式容器自动对其元素排序,自动排序带来的优势是:查找元素可以带来更高的效率。可以使用二分查找法,它具有对数(logarithmic)复杂度,而不是线性复杂度。

6.2.1序列式容器(SequenceContainer)

从vector开始讲,array是TR1新引入的,和原来的STL有点不搭。

Vector

Vetctor 将其元素置于一个dynamic array中管理。(这意思就是说可以随时添加元素呗)。

允许随机访问(就是允许用[i]来得到值呗)。

在array的尾部附加元素或移除元素都非常快,但是在array的中段或者起始部分安插元素就很慢,后面的元素都需要移动比较费劲了。

包含语句:include <vector>

下面语句创建了一个元素类型为int 的vecor:

vector <int> coll;

Push_back()为容器附加新元素:coll.push_back(i);所有序列式容器都提供这个函数,因为在尾巴那添加一个元素总是可能的,而且效率相当高。

Size()返回容器的元素个数。所有容器都由这个,除了forward_list 它没有(为啥没有?这个目前还没有说)。

Deque(double-ended queue的缩写)

是一个dynamic array,可以在两端发展,在头部和尾部添加元素都很快,在中间插入元素比较费劲。

包含语句:include <deque>

下面语句创建了一个元素类型为float的空的deque:

deque <float> coll;

Push_front()用来在最前面插入元素,Push_back()用来最后面插入元素。Vector并没有提供Push_front()因为太慢了。STL只提供那些具备良好时间效率的成员函数,所谓良好就是说时间复杂度为常量或者对数,以免菜鸟调用性能很差的函数。(是的,如果有,如果是我,我就说这没毛病,STL里面由这个函数,这肯定行!)

Array

一个array对象是有固定大小的array(有时可以称之为static array 或C array)。不可以改变元素个数,只能改变元素的值。必须在建立的时候就指明大小。运行随机访问。

包含语句:include <array>

下面语句创建了一个array,带有5个类型为string的元素:

Array <string,5> coll;默认情况下这些元素都被元素的default构造函数初始化。

List

从C++11开始,STL提供了两个List:class list<>和class  forward_list<>。

List由双向链表(double linked list)实现。意味着每个元素都有一部分内存指向前一个元素和其后继元素。

Lsit不提供随机访问,意味着如果你要访问第10个元素,你必须沿着链表依次走过前9个元素。因此一般的元素访问会花费较长的线性时间,这比vector和deque要慢很多了。

List的优势是:在任何位置上执行插入和删除动作都非常快,因为只改变链接就好了。也就是说在中间段移动元素比vector和deque快很多呢。

包含语句:include <list>

下面语句创建了一个元素类型为char的list:list <char> coll;

List 并不提供随机访问,因此操作符[]会带来低效率。(疑惑:到底是能不能用[]呢?待实践解惑)。

for(char elem :coll){} 或(auto elem:coll){}都可以,elem永远是当前正被处理的元素的一个拷贝。虽然你可以改动它,但是其影响只限于“针对此元素而调用的语句”,coll内部并没有任何东西被该动。如果你想改动传入的集合的元素,你必须将elem声明为一个非常量的reference:

for(auto& elem:coll){}

成员函数empty()的返回值告诉我们容器中是否还有元素。(是空的吗?False,就是说不是空的,!coll.emptey()就是true,循环就继续)

While(!coll.empty()){}

Front()返回第一个元素。

Pop_front()并不会返回被删除的元素,它是删除第一个元素。

forward_list

这是一个由元素构成的单方向的linked list,每一个元素都有一段内存,为了节省内存,只是指向了下一个元素。它就是个受限的list,它不支持任何后退移动或者效率低下的操作。基于这个原因,它不提供成员函数push_back()乃至size()。(这个我暂时无法理解,一定由什么原因在这里?)

Resize()可以改变元素的个数。

Resize()是个昂贵的动作,它具备线性的复杂度,因为想要到达尾部,你必须一个一个元素地前进,走遍整个list。

几乎所有的序列容器都会提供这resize,只有array没有,因为它是固定的大小,是固定不变的。

6.2.2关联式容器(AssociativeContainer)

关联式容器依据特定的排序规则,自动为其元素排序。元素可以是任何类型的value,也可以是key/value pair,key可以是任何类型,value也可以是任何类型。排序规则以函数形式呈现,用来比较key,或者key/value中的key,你可以提供自己的比较函数。

关联式容器由二叉树来实现,二叉树中每一个元素(节点)都有一个父节点和两个子节点,左子树的所有元素都比自己小,右子树都比自己大。

关联式容器的主要优点是:它能很快找出一个具有某个特定value的元素,因为它具备对数复杂度(logarithmic complexity),而序列式容器的复杂度为线性。

关联式容器的主要缺点是:你不能直接改变元素的value,因为那样就破坏了元素的排列顺序。

Set元素依据其value自动排序,每一个元素只能出现一次,不允许重复。

Multiset与Set的唯一区别就是元素可以重复,也就是说Multiset可以包含多个value相同的元素。

Map每个元素都是key/value  pair,其中key是排序准则的基准。每一个key只能出现一次,不允许重复。Map也可被视为一种关联式数组(associative array),也就是“索引可为任意类型”的数组。

Multimap与Map的唯一区别式:Multimap允许元素可以重复,也即是说Multimap允许其元素拥有相同的key。Multimap可以当作字典来使用。

所有关联式容器都有一个可供选择的template实参,它指明了排序准则;默认采用操作符<。

可以将set看作是一种特殊的map:元素的key和value是相等的。

包含语句:include<set>,来使用两个set。

包含语句:include<map>,来使用两个map。

6.2.3无序容器(UnorderedContainer)

在无序容器中,元素没有明确的排列次序。我们唯一关心的是元素是否位于容器内。可以把它想像为袋子。

无序容器常以hash table来实现出来,内部结构是一个由linked list组成的array。通过某个hash函数的运算,确定元素位于整个array的位置。Hash函数运算的目标是:让每个元素的落点位置有助于用户快速访问。

无序容器的主要优点是:当你打算查找某个特定值的元素,其速度可能会超过关联式容器,前提是你有个好的hash函数。

Unordered Set 是无序元素的集合,每一个元素只能出现一次,不能重复。

Unordered Multiset和Unordered Set 的唯一差别是允许重复。

Unordered Map的元素都是key/value pair,每个key只出现一次,不能重复。

Unordered Multimap和Unordered Map的唯一差别是允许重复。

C++标准库(第二版,作者_NicolaiMJosuttis)_第六章标准模板库_概述相关推荐

  1. 系统架构师学习笔记_第六章(下)_连载

    系统架构师学习笔记_第六章(下)_连载 6.3 基于 UML 的软件开发过程 6.3.1  开发过程概述 UML 是独立于软件开发过程的,能够在几乎任何一种软件开发过程中使用.迭代的渐进式软件开发过程 ...

  2. 算法竞赛入门经典(第二版)-刘汝佳-第六章 数据结构基础 习题(12/14)

    文章目录 说明 习题 习6-1 UVA 673 平衡的括号 习6-2 UVA 712 S - 树 习6-3 UVA 536 二叉树重建 习6-4 UVA 439 骑士的移动 习6-5 UVA 1600 ...

  3. C++标准库(第二版,作者_NicolaiMJosuttis)_第六章标准模板库_6.2.4关联式数组

    key/value pair 形式的集合也可以看作式一个关联式的数组,也即是索引并非整数的数组,因此这两个容器(map,unordered map)都提供了下标操作符[]. // STL_AssoAr ...

  4. 标准模板库之容器-《C++标准库(第二版)》读书笔记

    写在前面:本文是阅读<C++标准库(第二版)>的读书笔记. 文章目录 6.1 STL组件(Component) 6.2 容器(Container) 6.2.1 序列式容器(Sequence ...

  5. STL容器之Deque-《C++标准库(第二版)》读书笔记

    写在前面:本文是阅读<C++标准库(第二版)>的读书笔记. 文章目录 7.4 Deque 7.4.1 Deque的能力 7.4.2 Deque的操作函数 7.4.3 Exception H ...

  6. 通用工具之Pair和Tuple-《C++标准库(第二版)》读书笔记

    写在前面:本文是阅读<C++标准库(第二版)>的读书笔记. 文章目录 5.1 Pair 和Tuple 5.1.1 Pair 元素访问 构造函数和赋值 逐块式构造 便捷函数make_pair ...

  7. C语言入门书籍推荐:C语言程序设计:现代方法(第二版-作者K.N.King) APP推荐:微信读书

    C语言入门书籍推荐:C语言程序设计:现代方法(第二版-作者K.N.King)&& APP推荐:微信读书 结论 受众 第一种情况 第二种情况 读后感 利用微信读书 写在最后 结论 先说结 ...

  8. 电信保温杯笔记——《统计学习方法(第二版)——李航》第17章 潜在语义分析

    电信保温杯笔记--<统计学习方法(第二版)--李航>第17章 潜在语义分析 论文 介绍 单词向量空间 话题向量空间 话题向量空间 文本在话题向量空间的表示 从单词向量空间到话题向量空间的线 ...

  9. 电信保温杯笔记——《统计学习方法(第二版)——李航》第16章 主成分分析

    电信保温杯笔记--<统计学习方法(第二版)--李航>第16章 主成分分析 介绍 总体主成分分析 基本思路 直观解释 定义 主要性质 主成分个数 规范化变量 样本主成分分析 样本主成分的定义 ...

最新文章

  1. 汇编语言中,DS与BX有何区别?怎么搭配使用?(BX是通用寄存器)
  2. 安装 mysql-8.0.23-winx64
  3. 解决样本不平衡问题的奇技淫巧 汇总
  4. 【算法】算法岗需要顶会才能入场?
  5. 网络4/7层模型各层作用和协议对比
  6. atomic java_在Java中添加@atomic操作
  7. Sublime Text 3 配置python交互运行环境的快捷键
  8. 国际站 RDS MySQL 5.7 高可用版发布
  9. 今日测试:javascript笔试必考
  10. Magento教程 11:Inline Translation前台改文
  11. CISA:攻击者正在利用开源Zabbix服务器中的多个漏洞!
  12. java openfileoutput_java-openFileOutput在单例类中不能正常工作-想...
  13. 处理自己计算机某的端口被占问题
  14. 国标GB28181协议国标平台EasyGBS客户端作为上级平台如何跟下级海康8700平台对接?
  15. java 集合的并交差_java中计算集合的交差并集示例代码
  16. 统计成绩及格率和优秀率题目
  17. 此更新不适用您的计算机 win10,高手亲自讲解Win10系统提示此更新不适用于您的详尽处理办法...
  18. 方差分析ANOVA:理论、推导与R语言实现
  19. ArcGIS Engine基础(21)之面积测量(带内外环面积计算方法、地理坐标系和投影坐标系通用)
  20. Vert.x实战 异步数据和事件流

热门文章

  1. 计算机组成1046Q表示什么,计算器里的tanh是什么意思
  2. 图片怎么转换成PDF格式?这两种方法赶紧记下
  3. [CTFSHOW]中期测评WP(差512和514)
  4. Java的三种代理模式【附源码分析】
  5. 怎么关闭win10自带杀毒软件
  6. [转]Linux主机驱动与外设驱动分离思想
  7. 【杂】国内游戏创作大赛汇总(望补充)
  8. 报时功能_厦门宝藏 | 海关大钟悠扬的鸣曲报时,承载着老厦门人无数的记忆!...
  9. 浏览器input自动填充
  10. 广东省中医院微信公众号医保个账支付功能