Containers In STL¶
本节摘要
C++标准模板库中一些实用的容器模板
Introduction1¶
什么是容器
The Containers library is a generic collection of class templates and algorithms that allow programmers to easily implement common data structures like queues, lists and stacks.
容器是用于存储和管理数据的类模板,STL提供的容器大致分为三类:
- 序列容器
- 关联容器
- 无序容器
Sequence Container¶
序列容器是元素按照线性顺序存储的容器
Vector¶
std::vector 是封装动态数组的序列容器,元素被连续存储,可以通过迭代器和指向元素的常规指针进行访问
std::vector 的存储是自动管理的,按需扩样收缩,通常占用多于静态数组的空间,因为要分配更多内存用于管理将来的增长,而内存只在额外空间耗尽时进行重分配,使用 capacity() 查询分配的内存总量,可以使用 shrink_to_fit() 把多于的内存返回给系统
如果元素数量已知,可以使用 reserve() 消除内存重分配
容器复杂度特性:
- 随机访问: \(O(1)\)
- 在末尾插入或移除元素: \(O(1)\)
- 插入或移除元素: \(O(n)\)
| 成员函数 | 含义说明 |
|---|---|
| 元素访问 | ... |
at |
带越界检查访问指定元素 |
operator[] |
访问指定元素 |
front |
第一个元素 |
back |
最后一个元素 |
| 迭代器 | ... |
begin |
指向起始的迭代器 |
end |
指向末尾的迭代器 |
rbegin |
指向起始的逆向迭代器 |
rend |
指向末尾的逆向迭代器 |
| 容量 | ... |
empty |
是否为空 |
size |
元素数量 |
max_size |
可容纳的最大元素数 |
reserve |
预留存储空间 |
capacity |
当前存储空间能够容纳的元素数 |
| 修改器 | ... |
clear |
清除内容 |
insert |
插入元素 |
emplace1 |
原位构造元素 |
erase |
擦除元素 |
push_back |
末尾添加元素 |
emplace_back1 |
末尾原位构造元素 |
pop_back |
移除末尾元素 |
resize |
改变存储元素个数 |
Array1¶
固定大小的原位连续数组
TODO
Deque¶
双端队列
TODO
List¶
双向链表
TODO
Forward_list1¶
单向链表
TODO
Associative Container¶
关联容器是元素按照键值对存储的有序容器,支持 \(O(\log n)\) 级别复杂度的快速查找
Map¶
| map | |
|---|---|
std::map 是一种有序关联容器,包含唯一的键值对,键之间使用比较函数 Compare 排序
std::map 的底层实现通常为红黑树
std::map 的迭代器以升序迭代各键
容器复杂度特性:搜索、移除、插入操作的复杂度均为 \(O(\log n)\)
| 成员函数 | 含义说明 |
|---|---|
| 元素访问 | ... |
at |
带越界检查访问元素 |
operator[] |
访问或插入元素 |
| 迭代器 | ... |
begin |
指向起始的迭代器 |
end |
指向末尾的迭代器 |
rbegin |
指向起始的逆向迭代器 |
rend |
指向末尾的逆向迭代器 |
| 容量 | ... |
empty |
检查元素是否为空 |
size |
元素数 |
max_size |
可容纳的最大元素数 |
| 修改器 | ... |
clear |
清除内容 |
insert |
插入元素 |
emplace1 |
原位构造元素 |
try_emplace2 |
若键不存在则原位插入,否则不做任何事 |
erase |
擦除元素 |
merge2 |
从另一容器合并节点 |
| 查找 | ... |
count |
匹配特定键的元素数量 |
find |
寻找带有特定键的元素 |
lower_bound |
返回首个不小于给定键元素的迭代器 |
upper_bound |
返回首个大于给定键元素的迭代器 |
Set¶
| set | |
|---|---|
std::set 是一种关联容器,含有 Key 类型对象的已排序集,使用比较函数 Compare 进行
std::set 的底层实现通常为红黑树
容器复杂度特性:搜索、移除、插入操作的复杂度均为 \(O(\log n)\)
| 成员函数 | 含义说明 |
|---|---|
| 迭代器 | ... |
begin |
指向起始的迭代器 |
end |
指向末尾的迭代器 |
rbegin |
指向起始的逆向迭代器 |
rend |
指向末尾的逆向迭代器 |
| 容量 | ... |
empty |
检查元素是否为空 |
size |
元素数 |
max_size |
可容纳的最大元素数 |
| 修改器 | ... |
clear |
清除内容 |
insert |
插入元素 |
emplace1 |
原位构造元素 |
erase |
擦除元素 |
merge2 |
从另一容器合并节点 |
| 查找 | ... |
count |
匹配特定键的元素数量 |
find |
寻找带有特定键的元素 |
lower_bound |
返回首个不小于给定键元素的迭代器 |
upper_bound |
返回首个大于给定键元素的迭代器 |
Multimap¶
| map | |
|---|---|
std::multimap 是一种有序关联容器,含有键值对的已排序列表同时容许多个元素拥有同一键,键之间使用比较函数 Compare 排序
std::multimap 的迭代器以键的非降序进行迭代
拥有等价键的键值对的顺序就是插入顺序,且不会更改1
容器复杂度特性:搜索、移除、插入操作的复杂度均为 \(O(\log n)\)
| 成员函数 | 含义说明 |
|---|---|
| 迭代器 | ... |
begin |
指向起始的迭代器 |
end |
指向末尾的迭代器 |
rbegin |
指向起始的逆向迭代器 |
rend |
指向末尾的逆向迭代器 |
| 容量 | ... |
empty |
检查元素是否为空 |
size |
元素数 |
max_size |
可容纳的最大元素数 |
| 修改器 | ... |
clear |
清除内容 |
insert |
插入元素 |
emplace1 |
原位构造元素 |
erase |
擦除元素 |
merge2 |
从另一容器合并节点 |
| 查找 | ... |
count |
匹配特定键的元素数量 |
find |
寻找带有特定键的元素 |
lower_bound |
返回首个不小于给定键元素的迭代器 |
upper_bound |
返回首个大于给定键元素的迭代器 |
Multiset¶
| set | |
|---|---|
std::multiset 是一种关联容器,含有 Key 类型对象的有序集,允许多个 Key 拥有等价的值,使用比较函数 Compare 进行
比较等价元素间的顺序是插入顺序,而且不会更改1
容器复杂度特性:搜索、移除、插入操作的复杂度均为 \(O(\log n)\)
| 成员函数 | 含义说明 |
|---|---|
| 迭代器 | ... |
begin |
指向起始的迭代器 |
end |
指向末尾的迭代器 |
rbegin |
指向起始的逆向迭代器 |
rend |
指向末尾的逆向迭代器 |
| 容量 | ... |
empty |
检查元素是否为空 |
size |
元素数 |
max_size |
可容纳的最大元素数 |
| 修改器 | ... |
clear |
清除内容 |
insert |
插入元素 |
emplace1 |
原位构造元素 |
erase |
擦除元素 |
merge2 |
从另一容器合并节点 |
| 查找 | ... |
count |
匹配特定键的元素数量 |
find |
寻找带有特定键的元素 |
lower_bound |
返回首个不小于给定键元素的迭代器 |
upper_bound |
返回首个大于给定键元素的迭代器 |
Unordered Associative Container¶
无序关联容器,支持平均 \(O(1)\),最坏情况 \(O(n)\) 级别复杂度的无序数据结构
无序关联容器都是基于哈希表实现
Unordered_map1¶
| unordered_map | |
|---|---|
std::unordered_map 是一种关联容器,包含唯一的键值对
元素在容器内部不以任何特定顺序排序,而是组织进桶中,想通散列码的键出现在同一个桶
容器复杂度特性:搜索、移除、插入操作的平均复杂度均为 \(O(1)\)
| 成员函数 | 含义说明 |
|---|---|
| 元素访问 | ... |
at |
带越界检查访问元素 |
operator[] |
访问或插入元素 |
| 迭代器 | ... |
begin |
指向起始的迭代器 |
end |
指向末尾的迭代器 |
| 容量 | ... |
empty |
检查元素是否为空 |
size |
元素数 |
max_size |
可容纳的最大元素数 |
| 修改器 | ... |
clear |
清除内容 |
insert |
插入元素 |
emplace1 |
原位构造元素 |
try_emplace2 |
若键不存在则原位插入,否则不做任何事 |
erase |
擦除元素 |
merge2 |
从另一容器合并节点 |
| 查找 | ... |
count |
匹配特定键的元素数量 |
find |
寻找带有特定键的元素 |
Unordered_set1¶
| unordered_set | |
|---|---|
std::unordered_set 是一种关联容器,包含 Key 类型的唯一对象集合
元素在容器内部不以任何特定顺序排序,而是组织进桶中,想通散列码的键出现在同一个桶
注意
不可修改容器元素,因为修改可能改变元素散列并破坏容器
容器复杂度特性:搜索、移除、插入操作的平均复杂度均为 \(O(1)\)
| 成员函数 | 含义说明 |
|---|---|
| 迭代器 | ... |
begin |
指向起始的迭代器 |
end |
指向末尾的迭代器 |
| 容量 | ... |
empty |
检查元素是否为空 |
size |
元素数 |
max_size |
可容纳的最大元素数 |
| 修改器 | ... |
clear |
清除内容 |
insert |
插入元素 |
emplace1 |
原位构造元素 |
erase |
擦除元素 |
merge2 |
从另一容器合并节点 |
| 查找 | ... |
count |
匹配特定键的元素数量 |
find |
寻找带有特定键的元素 |
Unordered_multimap1¶
| unordered_map | |
|---|---|
std::unordered_multimap 是一种无序关联容器,支持等价键并将键与另一类型值关联,每个键值可能有多个副本
元素在容器内部不以任何特定顺序排序,而是组织进桶中,想通散列码的键出现在同一个桶
容器复杂度特性:搜索、移除、插入操作的平均复杂度均为 \(O(1)\)
| 成员函数 | 含义说明 |
|---|---|
| 迭代器 | ... |
begin |
指向起始的迭代器 |
end |
指向末尾的迭代器 |
| 容量 | ... |
empty |
检查元素是否为空 |
size |
元素数 |
max_size |
可容纳的最大元素数 |
| 修改器 | ... |
clear |
清除内容 |
insert |
插入元素 |
emplace1 |
原位构造元素 |
erase |
擦除元素 |
merge2 |
从另一容器合并节点 |
| 查找 | ... |
count |
匹配特定键的元素数量 |
find |
寻找带有特定键的元素 |
Unordered_set1¶
| unordered_set | |
|---|---|
std::unordered_multiset 是一种关联容器,包含可能非唯一的 Key 类型的对象集合
元素在容器内部不以任何特定顺序排序,而是组织进桶中,想通散列码的键出现在同一个桶
容器复杂度特性:搜索、移除、插入操作的平均复杂度均为 \(O(1)\)
| 成员函数 | 含义说明 |
|---|---|
| 迭代器 | ... |
begin |
指向起始的迭代器 |
end |
指向末尾的迭代器 |
| 容量 | ... |
empty |
检查元素是否为空 |
size |
元素数 |
max_size |
可容纳的最大元素数 |
| 修改器 | ... |
clear |
清除内容 |
insert |
插入元素 |
emplace1 |
原位构造元素 |
erase |
擦除元素 |
merge2 |
从另一容器合并节点 |
| 查找 | ... |
count |
匹配特定键的元素数量 |
find |
寻找带有特定键的元素 |
Container Adapters¶
容器适配器为顺序容器提供了不同接口
Stack¶
std::stack 是一种容器适配器,提供栈的功能
| 成员函数 | 含义说明 |
|---|---|
| 元素访问 | ... |
top |
访问栈顶元素 |
| 容量 | ... |
empty |
容器是否为空 |
size |
元素数量 |
| 修改器 | ... |
push |
栈顶插入元素 |
emplace1 |
栈顶原位构造元素 |
pop |
移除栈顶元素 |
Queue¶
std::queue 是一种容器适配器,提供队列的功能
| 成员函数 | 含义说明 |
|---|---|
| 元素访问 | ... |
front |
访问第一个元素 |
back |
访问最后一个元素 |
| 容量 | ... |
empty |
容器是否为空 |
size |
元素数量 |
| 修改器 | ... |
push |
栈顶插入元素 |
emplace1 |
栈顶原位构造元素 |
pop |
移除栈顶元素 |
Priority_queue¶
| queue | |
|---|---|
std::priority_queue 是一种容器适配器,提供优先队列的功能
适配器特性:
- 查找:默认查找最大元素,复杂度为 \(O(1)\)
- 插入:复杂度为 \(O(\log n)\)
最大堆与最小堆
可以使用 std::greater<T> 使得优先队列变为最小堆
| 成员函数 | 含义说明 |
|---|---|
| 元素访问 | ... |
top |
访问栈顶元素 |
| 容量 | ... |
empty |
容器是否为空 |
size |
元素数量 |
| 修改器 | ... |
push |
栈顶插入元素 |
emplace1 |
栈顶原位构造元素 |
pop |
移除栈顶元素 |