容器概览
容器分类
- 顺序容器提供对元素(半开)序列的访问。
- vector
- list
- forward_list
- deque
- 关联容器提供基于关键字的关联查询。
- 有序关联容器:通常用平衡二叉树(红黑树)实现。
- map
- multimap
- set
- multiset
- 无序关联容器:采用溢出链表法的哈希函数实现。
- unordered_map
- unordered_multimap
- unordered_set
- unordered_multiset
标准库,还提供了一些保存元素的对象类型,但它们并未提供顺序容器或关联容器的全部功能:
- 有序关联容器:通常用平衡二叉树(红黑树)实现。
- 容器适配器提供对底层容器的特殊访问。
- pirority_queue
- queue
- stack
- 拟容器保存元素序列,提供容器的大部分但非全部功能。
- array
- 内置数组
- string
- valarray
- bitset
对元素的要求
若想作为一个容器的元素,对象类型必须允许容器拷贝、移动以及交换元素。
关联容器要求其元素能够排序,很多可以应用于容器的算法也有这样的要求。
默认情况下,<
运算符被用来定义序。
排序标准必须定义一个严格弱序。
即,一个排序标准必须满足:
- 反自反性:不小于自身。
- 反对称性:两个操作对象不能同时小于对方;如果 x 小于 y,那么 y 绝不能小于 x。
- 传递性:如果 x 小于 y,且 y 小于 z,那么 x 必须小于 z。
- 相等的传递性:如果 x 等于 y,且 y 等于 z,那么 x 必须等于 z(
x == y
定义为!(x < y || y < x)
)。
顺序容器
vector 定义在<vector>
中;list 和 forward_list 定义在<list>
中;deque 定义在<deque>
中。
顺序容器为元素连续分配内存(vector 和 deque)或将元素组织为链表(list 和 forward_list )。
vector(以及类似的连续存储的元素的数据结构)有三个主要优势:
- vector 的元素是紧凑存储的。
- vector 的遍历非常快。
- vector 支持简单且高效的随机访问。
当在一个 vector 中插入、删除元素时,其它元素可能会移动。
一个空 forward_list 只占用一个内存字。
容器 | 功能 |
---|---|
vector<T,A> | 空间连续分配的 T 类型元素序列;默认选择容器 |
list<T,A> | T 类型元素双向列表;当需要插入或删除元素,但不移动已有元素时选择它 |
forward_list<T,A> | T 类型元素单向列表;很短或空序列的理想选择 |
deque<T,A> | T 类型元素双端队列;向量和链表的混合;对大多数应用而言,都比向量和链表其中之一要慢 |
模板参数 T 是元素类型;
模板参数 A 是一个分配器,容器用它来分配和释放内存;
A 的默认值是std::allocator<T>
,此分配器用operator new()
和operator delete()
为元素分配和释放内存。
有序关联容器
map 和 mutlimap 定义在头文件<map>
中;set 和 mutliset 定义在头文件<set>
中。
容器 | 功能 |
---|---|
map<K,V,C,A> | 从 K 到 V 的有序映射;一个(k,V)对序列 |
multimap<K,V,C,A> | 从 K 到 V 的有序映射;允许重复关键字 |
set<K,C,A> | K 的有序集合 |
multiset<K,C,A> | K 的有序集合,允许重复关键字 |
模板参数 K 为关键字类型,其默认序标准是std::less<K>
;
模板参数 V 为值类型;
模板参数 C 是比较类型;
模板参数 A 是一个分配器,容器用它来分配和释放内存;
对映射,A 的默认值是std::allocator<std::pair<const K,T>>
;
对集合,A 的默认值是std::allocator<T>
。
无序关联容器
无序容器则定义在头文 <unordered_map>
和<unordered_set>
中。
容器 | 功能 |
---|---|
unordered_map<K,V,H,E,A> | 从 K 到 V 的无序映射 |
unordered_set<K,V,H,E,A> | 从 K 到 V 的无序映射;允许重复关键字 |
unordered_multimap<K,H,E,A> | K 的无序集合 |
unordered_multiset<K,H,E,A> | K 的无序集合,允许重复关键字 |
模板参数 H 是哈希函数类型,其默认值是std::hash<K>
;
模板参数 E 是相等性判定函数类型,其默认值是std::equal_to<K>
。
容器适配器
容器 | 功能 |
---|---|
pirority_queue<T,C,Cmp> | T 的优先队列 |
queue<T,C> | T 的队列,支持 push() 和 pop() 操作 |
stack<T,C> | T 的栈,支持 push() 和 pop() 操作 |
模板参数 Cmp 是优先级函数类型,其默认值是std::less<T>
;
模版参数 C 是一个容器类型;
queue 的默认容器类型是std::dequeue<T>
;
stack 和 pirority_queue 的默认容器类型是std::vecter<T>
。
拟容器
容器 | 功能 |
---|---|
T[N] | 固定大小的内置数组;N 个连续存储的类型为 T 的元素;没有 size() 或其它成员函数 |
array[T,N] | 固定大小的数组;N 个连续存储的类型为 T 的元素;类似内置数组 |
basic_string<C,Tr,A> | 一个连续分配空间的类型为 C 的字符序列,支持文本操作(如连接 + 和 +=) |
string | basic_string<char> |
u16string | basic_string<char16_t> |
u32string | basic_string<char32_t> |
wstring | basic_string<wchar_t> |
valarray<T> | 数值向量,支持向量运算,但有一些限制,这些限制是为了鼓励高性能实现;只在做大量向量运算时使用 |
bitset[N] | N 个二进制位的集合,支持集合操作,如 & 和 |
vector<bool> | vector<T>的特例化版本,紧凑保存二进制 |
对于 basic_string,模板参数 A 是一个分配器,Tr 是字符萃取。