STL容器

STL广义上分为:容器(container)、算法(algorithm)、迭代器(iterator),容器和算法之间通过迭代器进行无缝连接

STL 六大组件:容器、算法、迭代器、仿函数、适配器(配接器)、空间配置器

容器:各种数据结构,如vector、list、deque、set、map等,从实现角度上看,STL容器是一种class template

算法:各种常用算法,如sort、find、copy、for_each等。从实现角度上看,STL算法是一种function template

迭代器:扮演容器与算法之间的粘合剂,共有五种类型,从实现角度上看,迭代器是一种将operator*, operator→, operator++, operator—等指针相关操作给予重载的class template。所有的STL容器都附带有自己专属的迭代器,只有容器的设计者才知道如何遍历自己的元素。原生指针(native pointer)也是一种迭代器。

仿函数:行为类似函数,可以作为算法的某种策略。从实现角度上看,仿函数是一种重载了operator()的class或者class template

适配器:一种用来修饰容器或者仿函数或者迭代器接口的东西

空间配置器:负责空间的配置与管理,从实现角度看,配置器是一个实现了动态空间配置、空间管理、空间释放的class template

六大组件的交互关系:

容器通过空间配置器取的数据存储空间,算法通过迭代器存储容器中的内容,仿函数可以协助算法完成不同的策略的变化,适配器可以修饰仿函数

优点:

  • STL是C++内在的一部分,不需要安装什么

  • STL的一个重要特性是将数据和操作分离。数据由容器类别加以管理,操作则由可制定的算法定义。迭代器在两者之间充当粘合剂,使得算法和容器可以交互运作。

  • 高可重用性,高性能,高移植性,跨平台

    高可重用性:STL几乎所有的代码都采用了模板类和模板函数进行实现的

    高性能:如map可以高效地在十万条记录中找出指定的记录,map采用的是红黑树的变体实现的

    高移植性:项目之间可以快速移植

    跨平台:

STL 三大组件

容器

序列式容器

每个元素有固定的位置,除非用删除或者插入进行改变。比如vector, deque, list等

关联式容器

各元素没有严格的物理上的顺序关系,元素在容器中并没有保存元素插入容器时的逻辑顺序,比如set multiset map multimap等。另一个特定是使用关键字进行索引。

算法

质变算法

会改变区间元素中的内容,比如拷贝、替换、删除等

非质变算法

不会改变区间的元素内容,比如查找,计数,遍历等

迭代器

iterator定义如下:提供一种方法,使之能够依序寻访某个容器中所含的各个元素,而又无需暴露该容器的内部表示方式。

分为五类,输入、输出、前向、双向、随机访问迭代器。

常用容器

string 容器

构造函数

基本赋值操作

存取操作

拼接操作

查找和替换

比较

子串

插入和删除

string 和 c-style字符串转换

补充

vector 容器

和数组array的唯一差别在于空间的灵活性

vector 构造函数

赋值操作

大小操作

数据存取

插入和删除

其他

deque 容器

deque属于双端数组, vector也可以进行头插,但是效率很低

deque内部用的是中控器(保存缓冲区的地址)+缓冲区的结果

大部分的操作和vector是一样的e

Sort算法

Stack 容器

先进后出的数据结构:First In Last Out(FILO),只能访问栈顶元素

构造

存取操作

queue 容器

队列容器,先进先出的数据结构First In First Out(FIFO),只允许由一端入队,一端出队,不提供遍历和迭代器

List 容器

List容器是一个双向循环链表,动态分配存储信息,消耗较大

List容器提供的迭代器是bidirectional Iterators, 不支持随机访问

List有一个重要性质,插入操作和删除操作不会造成原有迭代器的失效。这个在Vector容器中是不成立的,因为vector容器的插入操作可能引起内存的重新分配,导致原有的迭代器失效。

也可以支持逆序遍历,reverse_iterator

set、multiset容器

set容器的特性,所有的元素都会根据元素的键值自动排序,set的元素不像map那样可以同时拥有实值和键值,set元素既是键值又是实值。set不允许两个元素有相同的键值。

不可以通过set的迭代器来改变set容器的元素值,换句话说,set的迭代器是一种const_iterator

set有和list一样的性质,原有的迭代器在插入删除元素后还是有效的,当然,被删除那个元素的迭代器除外。

multiset特性和set完全相通,唯一的差别在于multiset允许键值重复。set、multiset的话底层是用红黑树实现的。

相关操作和上面提到的操作基本一致,不在说明。

Pair对组

map、multimap容器

map的特性是会根据元素的键值自动排序,map所有的元素都是pair,同时拥有键值和实值,pair的第一个元素被视为键值,第二个元素被视为实值,同样和set一样,map也是不允许有两个元素有相同的键值(注意这里是键值,key值,value值可以相同)。

同样map也是不能根据迭代器更改元素内容的。

map和list一样,插入删除元素迭代器不失效。

multimap可以支持键值重复。

multimap案例:存储员工信息:姓名 年龄 电话 工资等

STL使用时机

vector使用场景:比如软件的历史操作记录的存储。

deque使用场景:比如排队购票系统

vector与deque的比较:

  1. vector.at()比deque.at()的效率高,因为vector.at(0)是固定的,而deque的开始位置是不固定的

  2. 如果有大量的释放操作的话,vector花费的时间更少

  3. deque支持头部的快速插入和删除,是属于deque的优点

list的使用场景,公交车乘客信息的存储,随时有可能乘客下车,存在频繁的不确定位置元素的插入和删除

set的使用场景:手机游戏的个人得分的存储,要求从高分到低分顺序存储

map使用场景:比如按照ID账号存储十万个账号。

Last updated

Was this helpful?