前言
顺序容器(sequential container):将单一数据类型聚集起来的容器,可以根据位置来存储和访问元素
顺序容器种类:
1. vector(支持随机访问)
2. list(支持快速插入和删除)
3. deque(double ended queue)(双端口队列)
适配器(adaptor):根据原始的容器类型所提供的操作,通过定义新的操作接口,来实现新的功能
适配器种类:
1. stack(LIFO)
2. queue(FIFO)
3. priority_queue(优先队列)
1 顺序容器的定义
1.1 在使用顺序容器时,必须要包含顺序容器的头文件
#include <vector>
#include <list>
#include <deque>
1.2 在定义顺序容器时,必须指明数据类型
vector<type> name
list<type> name
deque<type> name
2 顺序容器的初始化
2.1 利用已有容器初始化另一个容器
vector<int> vect;
vector<int> vect2(vect)
2.2 利用已有容器的一段数据初始化另一个容器
vector<int> ::iterator mid = vect.begin() + vect.size()/2
vector<int>vect3(vect.begin(),mid)
2.3 设置容器的大小和初始化值
const vector<int>::size_type len = 100
vector<int>vect4(len, 0)
3 迭代器和迭代器范围
3.1 迭代器的运行(基本运行)
*iterator | iterator-> | ||
---|---|---|---|
++iterator | –iterator | iterator++ | iterator– |
iter1 == iter2 | iter1 != iter2 |
3.2 迭代器(vector/deque)
iter+n | iter-n | ||
---|---|---|---|
iter+=iter2 | iter-=iter2 | iter-iter2 | |
iter < iter2 | iter>iter2 | iter<=iter2 | iter>=iter2 |
3.3 迭代器的作用范围
左闭右开区间 ==》 [ c.begin() c.end() )
3.4 迭代器失效
1. 如果对容器进行 添加、删除 操作时会使迭代器失效(修改容器内数据的个数时,迭代器会失效)
2. 避免存储迭代器end(),修改迭代器时一定会修改迭代器end() ==》 可以通过实时的获取迭代器end()来避免迭代器的失效
4 顺序容器的操作
4.1 顺序容器常用的数据类型
- size_type : 无符号整形,表示容器的长度
- iterator : 迭代器,指针类型变量
- const_iterator
- reverse_iterator
- const_reverse_iterator
- difference_type
- value_type
- reference
- const_reference
4.2 容器的范围表示
函数 | 说明 |
---|---|
begin() | 起始位置 |
end() | 结束位置 |
4.3 添加元素
函数 | 说明 |
---|---|
push_back(t) | 在容器尾插入元素 |
push_front(t) | 在容器头插入元素 |
insert(p,t) | 在迭代器p的前面插入元素值为t的元素 |
insert(p,n,t) | 在迭代器p的前面插入n个元素值为t的元素 |
insert(p,b,e) | 在迭代器p的前面插入从迭代器b到迭代器e之间的数据 |
4.4 大小比较
- 只能同类型的容器在一起进行比较
- 只能同类型的数据在一起进行比较
比较关系 | 说明 |
---|---|
== | 两个容器的大小相同,容器内的数据也相同(顺序也相同) |
< | 一个容器是另一个容器的子集,如果两个容器互相不为对方的子集,那么容器大小的比较结果由第一个元素的大小比较结果决定 |
4.5 容器大小
函数 | 说明 |
---|---|
size() | 返回容器数据元素的个数,类型为size_type |
max_size() | 最大可以容纳的元素个数,size_type |
empty() | 容器空判断,bool |
resize(n) | 调整容器的大小为n |
resize(n,t) | 调整容器的大小为n,新添加的元素初始化为t |
4.6 访问元素
函数 | 说明 |
---|---|
back() | 最后一个元素 |
front() | 第一个元素 |
[n] | 第n个元素,无越界处理 |
at(n) | 第n个元素,有越界处理 |
4.7 删除元素
函数 | 说明 |
---|---|
pop_back() | 删除最后一个元素,返回void |
pop_front() | 删除第一个元素,返回void,且仅list和deque可用 |
erase(p) | 删除迭代器p指向的元素,并返回p的后一个迭代器的位置 |
erase(b,e) | 删除迭代器b和迭代器e之间的数据,返回e之后迭代器的位置 |
clear() | 删除所有的元素,返回void |
注:对于erase而已,被删除的元素必须存在,而且删除的数据范围必须有效,如果输入的数据无效,函数的定义是未知的。
4.8 赋值与交换
函数 | 说明 |
---|---|
c1 = c2 | c1和c2的类型必须一致 = erase+insert |
c1.swap(c2) | 交换c1和c2的值 没有任何删除和插入操作 |
assign(b,e) | 将迭代器b和迭代器e之间的数据复制容器 = erase + insert |
assign(n,t) | 将容器重置为n个值为t的容器 |
注:vector特有的两个接口函数:
- capacity:容量(实际开辟的内存空间大小)
- reserve:预留量(提前开辟的内存空间大小)
注:对vector进行erase操作不会删除申请申请的内存,其容量是不变的,size会变成零,因此要回收一个vector容器的内存,可以通过resize方法或者swap一个空的容器
5 容器适配器
标准库(STL)通过调整顺序容器(vector, list, deque)的接口,形成了三个新的容器,称为容器适配器,分别为:
- stack(LIFO) 栈
- queue(FIFO) 队列
- priority_queue 优先队列
5.1 适配器的数据类型
数据类型以及操作 | 说明 |
---|---|
size_type | 适配器存储最大对象的长度(就是适配器的元素个数,同sizeof(type)) |
value_type | 元素类型 |
关系操作符 | 三个适配器都支持 == != < > <= >= |
注:适配器的默认构造函数用于构造一个空的适配器,带有参数构造函数可以初始化适配器的值。
5.2 栈 stack
栈是计算机中经常使用的数据结构之一,栈的结构比较简单,只要基本的三个操作,即入栈、出栈以及取值,STL中的栈的操作如下:
函数 | 说明 |
---|---|
empty() | 栈空检测,如果栈为空就返回true,否则就返回false |
size() | 返回栈中元素的个数,返回值类型为size_type |
push() | 压栈,返回值为void |
pop() | 出栈,返回值为void |
top() | 取栈顶元素 |
5.3 队列和优先队列
注:优先队列(priority queue)默认使用“<”作为元素之间优先级的关系
注2:在使用队列以及优先队列时,要添加对头文件queue的引用
在STL中队列以及优先队列的操作如下:
函数 | 说明 |
---|---|
empty() | 判断队列是否为空,为空就返回true,否则就返回false |
size() | 返回队列中元素的个数 |
push() | 数据入队,返回值为void |
pop() | 数据出队,返回值为void |
front() | 取队首元素(仅queue可用) |
back() | 取队尾元素(仅queue可用) |
top() | 取具有最高优先级的元素(仅priorty_queue可用) |
补充:优先队列的用法
#include <queue> //要包含这个头文件
priorty_queue<int> pq; //采用默认的优先级(<)
priorty_queue<int, vector<int>, less<int>> pq2; //采用不同的优先级
其中第二个参数( vector ),是来承载底层数据结构堆的容器,第三个参数( less ),则是一个比较类,less 表示数字大的优先级高,而 greater 表示数字小的优先级高。
注:对于复合数据类型(如struct)要自己重载“<”运算符