C++系列-STL标准库
STL组成
- 容器
- 配接器
- 算法
- 迭代器
- 仿函数
- 空间配置器
主要讲解容器和算法,不讲解其他的
容器分类
- 序列式容器:
vector
list
deque
stack
queue
heap
priority_quue
slist
(queue
和stack
是配接器) - 关联式容器:
set
map
multiset
multimap
hash_set
hash_map
hash_multiset
hash_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
- 双向开口的连续空间
- 两端插入和删除操作都是
- 分段连续空间组合而成,避免了重新配置、复制、释放的轮回
- 对
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
两个操作
红黑树
- 是容器,但是不开放使用,是
map
set
的底层实现 - 时间复杂度是
- 是个二叉搜索树,同时满足下列规则
- 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
采用开链方法解决冲突
线性探测
有冲突,直接循环往下一一寻找,直到一个可用的空间为止;删除时采用惰性删除,实际删除需要重新整理时再进行
问题:平均插入成本的成长幅度,远高于负载系数的成长幅度(主集团现象)
二次探测
主要用来解决主集团问题;如果有冲突,尝试
如果表格大小为质数,且永远保持负载系数在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源码剖析
本文作者:xnzone
本文链接:https://www.cnblogs.com/xnzone/p/14430426.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步