C++系列-STL标准库
STL组成
- 容器
- 配接器
- 算法
- 迭代器
- 仿函数
- 空间配置器
主要讲解容器和算法,不讲解其他的
容器分类
- 序列式容器:
vectorlistdequestackqueueheappriority_quueslist(queue和stack是配接器) - 关联式容器:
setmapmultisetmultimaphash_sethash_maphash_multisethash_multimap
vector
- 连续空间
- vector 动态空间
- array 静态空间
- 动态空间是以原大小的两倍进行扩充,重新分配时,迭代器会失效
主要操作有push_back pop_back erase clear insert size empty
初始化
#include <vector>
int main(){
// size=0的vector
vector<int> a;
// 初始化size,但元素为默认值
vector<int> b(10);
// 初始化size并设置默认值
vector<int> b(10,2);
}
list
- 非连续空间
- STL的list是一个环状双向链表
- 插入和删除操作都不会造成原迭代器失效
主要操作有:push_front push_back erase pop_front pop_back clear remove unique splice merge reverse sort size empty
内部定义了一个transfer函数,为splice sort merge等操作提供基础。功能是将连续范围内的元素迁移到某个特定位置之前
deque
- 双向开口的连续空间
- 两端插入和删除操作都是\(O(1)\)
- 分段连续空间组合而成,避免了重新配置、复制、释放的轮回
- 对
deque的排序只能复制到一个vector然后根据sort算法,再复制回deque
原理
- 用一个小块连续空间作为主控
- 每个元素都是指针,指向另一个大的连续线性空间,称为缓冲区
- 缓冲区才是
deque存储空间的主题

主要操作有:push_front push_back pop_front pop_back clear erase insert size empty
stack
- 先进后出的结构,只有一个出口
- STL使用
deque作为底层源码进行实现 - 没有迭代器
- 也有使用它
list作为底层源码进行实现
主要操作有:empty size back push_back pop_back
queue
- 先进先出结构,有两个出口
- STL以
deque作为底层源码进行实现 - 没有迭代器
- 也有使用
list作为底层源码进行实现
主要操作有:empty size front back push pop
heap
- 不归属于STL容器组件,但是是
priority_queue的底层实现 - 二叉堆是一个完全二叉树,除叶节点外,都是填满的,且叶节点左右不得有空隙
- 可以使用
array存储所有节点 - 某个节点位于
i处时,左子节点位于2i处,右子节点位于2i+1处,父节点在i/2处 - 分为最大堆和最小堆
- STL提供的是最大堆
heap不提供遍历功能,也不提供迭代器
原理
- push操作:先插入到
vector尾部,然后进行上溯:新节点与父节点比较,如果比父节点大,父子调换位置 - pop操作: 取走根节点后,把最下层最右边节点进行下溯:空间节点与较大子节点调换位置,直到叶节点为止
priority_queue
- 优先队列,根据权值进行排序,默认情况是一个最大堆
- 以
heap为源码作为底层实现 - 没有迭代器
主要操作有:size empty top push
slist
- 双向列表
- 不在标准规格之内,有些STL不提供
- 与list相比没有回溯节点的操作
- 提供了
insert_after和erase_after两个操作
红黑树
- 是容器,但是不开放使用,是
mapset的底层实现 - 时间复杂度是\(log_2n\)
- 是个二叉搜索树,同时满足下列规则
- 1.每个节点不是红色就是黑色
- 2.根节点是黑色
- 3.如果节点为红色,子节点必须是黑色
- 4.任一节点至NULL的任何路径,所含之黑节点数必须相同
根据规则4,新增节点必须是红色,根据规则3,新增节点的父节点必须是黑色,如果不满足,必须调整红黑树
主要提供:insert_unique insert_equal和find三个方法。insert_unique不允许重复,insert_equal每次插入都会成功,find遵循二叉搜索树的性质(左 < 根 < 右)
set
- 所有元素的键值都会自动被排序
- 不允许有两个相同的键值
- 不允许修改
set的键值 - 新增或删除时,迭代器不会失效
- 以红黑树作为底层实现
- 拥有交、并、差集合运算
主要提供的操作有:insert erase size clear find empty
map
- 元素会根据键值进行自动排序
- 所有元素都是
pair - 不允许有两个相同的键
- 不可以修改键,可以修改值
- 新增和删除操作,迭代器不会失效
主要提供的操作有:insert erase size empty clear find 下标操作
multiset
- 和
set完全相同,唯一差别在于允许键值重复
multimap
- 和
map完全相同,唯一差别在于允许键值重复
hashtable
- 常数平均时间的复杂度
- 需要用散列函数将一个元素映射为一个大小可接受的索引
- 如果映射索引有冲突,需要通过一些列办法解决冲突,如线性探测,二次探测,开链等做法
hashtable采用开链方法解决冲突
线性探测
有冲突,直接循环往下一一寻找,直到一个可用的空间为止;删除时采用惰性删除,实际删除需要重新整理时再进行
问题:平均插入成本的成长幅度,远高于负载系数的成长幅度(主集团现象)
二次探测
主要用来解决主集团问题;如果有冲突,尝试\(H+1^2,H+2^2,H+3^2,...,H+i^2\)
如果表格大小为质数,且永远保持负载系数在0.5以下(超过0.5重新整理),每次插入不超过2次探测
问题:计算出来的位置相同,则插入的位置也相同,会造成浪费(次集团现象)
解决办法有:复式散列等
开链
每个表格元素维护一个list,冲突时,在list上插入、搜寻等操作
hash_set
- 以
hashtable为底层实现机制 - 没有自动排序的功能
- 使用和性质与
set完全一样
hash_multiset
- 与
multiset完全一样,没有排序功能
hash_map
- 以
hashtable为底层实现机制 - 没有自动排序功能
- 使用性质和
map完全一样
hash_multimap
- 与
multimap完全一样,没有排序功能
算法
包含的一些主要算法有: binary_search copy find find_if find_first_of max max_element lower_bound min min_element reverse rotate search search_n set_difference set_intersection set_union sort stable_sort swap upper_bound make_heap pop_heap push_heap sort_heap
算法的操作一般都是迭代器
参考文献
STL源码剖析

浙公网安备 33010602011771号