STL学习总结

一.1、什么是标准模板库(STL)?

(1)C++标准模板库与C++标准库的关系

C++标准模板库其实属于C++标准库的一部分,C++标准模板库主要是定义了标准模板的定义与声明,而这些模板主要都是

类模板,我们可以调用这些模板来定义一个具体的类;与之前的自己手动创建一个函数模版或者是类模板不一样,我们使用了

STL就不用自己来创建模板了,这些模板都定义在标准模板库中,我们只需要学会怎么使用这些类模板来定义一个具体的类,

然后能够使用类提供的各种方法来处理数据。

(2)STL六大组件:容器(containers)、算法(algorithms)、迭代器(iterators)、函数对象(functors)、适配器(adapters)、分配器(allocators)

2、迭代器

迭代器是一种对象,它能够用来遍历STL容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址,所以可以认为迭代器其实就是用来指向容器中数

据的指针,我们可以通过改变这个指针来遍历容器中的所有元素。

3、容器

首先,我们必须理解一下什么是容器,对比我们生活当中的容器,例如水杯、桶、水瓶等等这些东西,其实他们都是容器,他们的一个共同点就是:都是用来

存放液体的,能够用来存放一些东西;其实在我们的C++中说的这个容器其实作用也是用来存放"东西",但是存放的是数据,在C++中容器就是一种用来存放

数据的对象。

(1)C++中的容器其实是容器类实例化之后的一个具体的对象,那么可以办这个对象看成就是一个容器。

(2)因为C++中容器类是基于类模板定义的,也就是我们这里说的STL(标准模板类)。为什么需要做成模板的形式呢?因为我们的容器中存放的数据类型其实

是相同的,如果就因为数据类型不同而要定义多个具体的类,这样就不合适,而模板恰好又能够解决这种问题,所以C++中的容器类是通过类模板的方式定义的

,也就是STL。

(3)容器还有另一个特点是容器可以自行扩展。在解决问题时我们常常不知道我们需要存储多少个对象,也就是说我们不知道应该创建多大的内存空间来存放我们

的数据。显然,数组在这一方面也力不从心。容器的优势就在这里,它不需要你预先告诉它你要存储多少对象,只要你创建一个容器对象,并合理的调用它所提

供的方法,所有的处理细节将由容器来自身完成。它可以为你申请内存或释放内存,并且用最优的算法来执行您的命令。

(4)容器是随着面向对象语言的诞生而提出的,容器类在面向对象语言中特别重要,甚至它被认为是早期面向对象语言的基础。

4、容器的分类

STL对定义的通用容器分三类:顺序性容器关联式容器容器适配器

我想说的是对于上面的每种类型的容器到底是是什么意思,其实没必要去搞懂,没什么价值,只要你能够大概理解知道即可,知道每种容器类型下有哪些具体的容器

即可。

顺序性容器:vector、deque、list

关联性容器:set、multiset、map、multimap

容器适配器:stack、queue、

1.vector向量

vector向量是一种顺序行容器。相当于数组,但其大小可以不预先指定,并且自动扩展。它可以像数组一样被操作,由于它的特性我们完全可以将vector 看作动态数组。

在创建一个vector 后,它会自动在内存中分配一块连续的内存空间进行数据存储,初始的空间大小可以预先指定也可以由vector 默认指定。当存储的数据超过分配的

空间时vector 会重新分配一块内存块,但这样的分配是很耗时的,在重新分配空间时它会做这样的动作:

首先,vector 会申请一块更大的内存块;

然后,将原来的数据拷贝到新的内存块中;

其次,销毁掉原内存块中的对象(调用对象的析构函数);

最后,将原来的内存空间释放掉。

当vector保存的数据量很大时,如果此时进行插入数据导致需要更大的空间来存放这些数据量,那么将会大大的影响程序运行的效率,所以我们应该合理的使用vector。

 (1)初始化vector对象的方式:

vector<T> v1;     // 默认的初始化方式,内容为空

vector<T> v2(v1);   // v2是v1的一个副本

vector<T> v3(n, i)   // v3中包含了n个数值为i的元素

vector<T> v4(n);   // v4中包含了n个元素,每个元素的值都是0

(2)vector常用函数

empty():判断向量是否为空,为空返回真,否则为假

begin():返回向量(数组)的首元素地址

end(): 返回向量(数组)的末元素的下一个元素的地址

clear():清空向量

front():返回得到向量的第一个元素的数据

back():返回得到向量的最后一个元素的数据

size():返回得到向量中元素的个数

push_back(数据):将数据插入到向量的尾部

pop_back():删除向量尾部的数据

.....

2.map

Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。map内部自建一颗红黑树(一 种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的。至于二叉树这种数据结构,本人暂时没有任何了解。在map这个容器中,提供一种“键- 值”关系的一对一的数据存储能力。其“键”在容器中不可重复,且按一定顺序排列,至于怎么排列,那么红黑树这种数据结构的特性了。

STL学习总结

 

(1)初始化map对象的方式

map<int, string> m1 = { { 1, "guangzhou" }, { 2, "shenzhen" }, { 3, "changsha" } };   // 实例化一个map容器,还有3组数据
map<char, string> m2;             // 实例化一个空map容器

(2)map常用函数

begin():返回容器第一个元素的迭代器

end():返回容器最后一个元素之后的迭代器

rbegin():

rend():

clera():清除容器中所有元素

empty():判断容器是否为空

insert(p1):插入元素  p1 是通过pair函数建立的映射关系对

insert(pair<char, string>('S', "shenzhen")): 插入元素

size():返回容器中元素的个数

count():返回指定键对应的数据的出现的次数

get_allocator():返回map的配置器

swap():交换两个map容器的元素

.....

遍历方式

map容器支持迭代器正向方式遍历和迭代器反向方式遍历,同时也支持 [] 方式访问数据,[]中的索引值是键值,这个一定要清楚

3.set

使用平衡二叉树管理元素
集合(Set)是一种包含已排序对象的关联容器。
必须包含的头文件#include <set>
map容器是键-值对的集合,好比以人名为键的地址和电话号码。相反地,set容器只是单纯的键的集合。当我们想知道某位用户是否存在时,使用set容器是最合适的。
set中不允许key相同的元素,multiset允许key相同的元素
4.pair

pair模板可以用于生成key-value

5.顺序性容器和关联容器

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

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

二.Algorithm

 

STL算法部分主要由头文件<algorithm>,<numeric>,<functional>组成。要使用 STL中的算法函数必须包含头文件<algorithm>,对于数值算法须包含<numeric><functional>中则定义了一些模板类,用来声明函数对象。
    STL中算法大致分为四类:
        1非可变序列算法:指不直接修改其所操作的容器内容的算法。
        2可变序列算法:指可以修改它们所操作的容器内容的算法。
        3排序算法:包括对序列进行排序和合并的算法、搜索算法以及有序序列上的集合操作。
        4数值算法:对容器内容进行数值计算。