顺序容器:存储元素,元素位置由加入容器时顺序决定。
关联容器:存储元素,元素位置由关键字 key 决定。
所有容器共享公共接口,各自实现不同。
顺序容器:快速顺序访问元素。
性能代价:
vector:可变大小数组。支持随机访问(连续内存存储)。尾部插入或删除元素时间复杂度为O(1),其他位置插入或删除元素时间复杂度为O(n)。
deque:双端队列。支持随机访问(连续内存存储)。
顺序容器类型 | 说明 | 访问 | 头插 O | 头删 O | 尾插 O | 尾删 O | 除头尾位置插入或删除 | 查找元素时间复杂度 |
---|---|---|---|---|---|---|---|---|
vector | 可变大小数组。 | 快速随机访问。 | 不支持 | 不支持 | O(1) | O(1) | O(n) | O(n) |
deque | 双端队列。 | 快速随机访问。 | O(1) | O(1) | O(1) | O(1) | O(n) | O(n) |
list | 双向链表。 | 只支持双向顺序访问。 | O(1) | O(1) | O(1) | O(1) | O(1) | O(1) |
forward_list | 单向链表。 | 只支持单向顺序访问。 | O(1) | O(1) | O(1) | O(1) | O(1) | O(1) |
array | 固定大小数组。 | 快速随机访问。 | 不支持 | 不支持 | 不支持 | 不支持 | 不支持 | 不支持 |
string | 与 vector 相似,保存字符的容器。 | 快速随机访问。 | 不支持 | 不支持 | O(1) | O(1) | O(n) | O(n) |
除 array 其他容器支持高效、灵活的内存管理,可以添加、删除元素,扩张和收缩容器大小。
存储策略影响容器支持的操作。
array 比内置数组更安全,更容易使用。
forward_list 没有 size 操作,其他容器 size 是常量时间操作。
尽可能使用C++标准库。
确定使用哪种顺序容器:
不确定,只使用 vector 和 lsit 的公共操作:使用迭代器,不使用下标,避免随机访问。
切换容器方便。
容器定在与类型名相同的头文件中。
容器是模板,提供额外信息生成特定容器类型。
容器元素可以是任意类型。
为不支持特定操作的类型定义容器,就只能使用没有特殊要求的容器操作:
顺序容器构造函数一个版本接受容器大小,使用元素类型的默认构造函数。某些类没有默认构造函数,定义一个保存这种类型对象的容器,构造容器是不能只传递元素数目参数:
//noDefault 没有默认构造函数
vector<noDefault> v1(10, init); //提供元素初始化器。
vector<noDefault> v1(20); //错误,必须提供元素初始化器。
类型别名 | 类型 | 作用 |
---|---|---|
iterator | 此容器类型的迭代器类型。 | 可读可写容器元素。 |
const_iterator | 只读迭代器类型。 | 只读容器元素。 |
size_type | 无符号整数类型。 | 容器元素数量。 |
difference_type | 带符号整数类型。 | 两个迭代器之间的距离。 |
value_type | 元素类型。 | 获取容器元素类型。 |
reference | value_type & | 元素的左值类型。 |
const_reference | const value_type & | 元素的 const 左值类型。 |
构造函数 | 说明 |
---|---|
C c; | 默认构造函数,构造空容器。 |
C c1(c2); | 构造 c2 的拷贝 c1。 |
C c(b, e); | 使用迭代器 b 和 e 范围内的元素构造 c。(array不支持) |
C c{a, b, c……} | 列表初始化c |
赋值和swap | 说明 |
---|---|
c1 = c2 | c2 中的元素替换c1 中的元素。 |
c1 = {a, b, c, ……} | 列表元素替换 c1 中的元素。(array不适用) |
a.swap(b) | 交换 a 和 b 的元素。 |
swap(a, b) | 与 a.swap(b) 等价。 |
大小 | 说明 |
---|---|
c.size() | c 中元素的数量。(forward_list 不支持) |
c.max_zise() | c 可保存的最大元素数量。 |
c.empty() | 为空返回 true,不为空返回 false。 |
添加 / 删除元素(不适用 array)【注:不同容器操作接口不同】 | 说明 |
---|---|
c.insert(args) | 将 args 中的元素拷贝进 c。 |
c.emplace(inits) | 使用 inits 构造 c 中的一个元素。 |
c.erase(args) | 删除 args 指定的元素。 |
c.clear() | 删除 c 中所有元素,返回 void。 |
关系运算符 | 说明 |
---|---|
==, != | 所有容器都支持。 |
<, <=, >, >= | 无序关联容器不支持。 |
获取迭代器 | 说明 |
---|---|
c.begin(), c.eng() | 返回 c 的首元素和尾元素之后位置的迭代器。 |
c.cbegin(), c.ceng() | 返回 const_iterator |
反向容器的额外成员。(forward_list不支持) | 说明 |
---|---|
reverse_iterator | 逆序寻址元素的迭代器。 |
const_reverse_iterator | 不可修改的逆序寻址元素的迭代器。 |
c.rbegin(), c.rend() | 返回指向 c 的尾元素和首元素之前位置的迭代器。 |
c.crbegin(), c.crend() | 返回 const_reverse_iterator |
提供相同操作的迭代器对操作的实现方式相同:
所有迭代器都允许访问容器中的元素且都通过解引用来实现。
所有迭代器都定义了递增运算符,从当前元素移动到下一个元素。
forward_list 不支持迭代 --。
支持迭代器算术运算:string、vector、deque 和 array。(这些容器底层内存连续存储空间)
迭代器范围:[begin, end)
迭代器范围要求:(程序员的责任)
类型别名 | 类型 | 作用 |
---|---|---|
iterator | 此容器类型的迭代器类型。 | 可读可写容器元素。 |
const_iterator | 只读迭代器类型。 | 只读容器元素。 |
size_type | 无符号整数类型。 | 容器元素数量。 |
difference_type | 带符号整数类型。 | 两个迭代器之间的距离。 |
value_type | 元素类型。 | 获取容器元素类型。 |
reference | value_type & | 元素的左值类型。 |
const_reference | const value_type & | 元素的 const 左值类型。 |
begin 生成指向容器中的第一个元素的迭代器。
end 生成指向容器中的尾元素之后位置的迭代器。
获取迭代器 | 说明 |
---|---|
c.begin(), c.eng() | 返回 c 的首元素和尾元素之后位置的迭代器。 |
c.cbegin(), c.ceng() | 返回 const_iterator |
反向容器的额外成员。(forward_list不支持) | 说明 |
---|---|
reverse_iterator | 逆序寻址元素的迭代器。 |
const_reverse_iterator | 不可修改的逆序寻址元素的迭代器。 |
c.rbegin(), c.rend() | 返回指向 c 的尾元素和首元素之前位置的迭代器。 |
c.crbegin(), c.crend() | 返回 const_reverse_iterator |
r:反向迭代器。
c:返回 const 迭代器。
不以c开头的函数被重载过,const 成员返回 const_iterator。no-const 成员返回 iterator。
no-const 对象返回 iterator。
const 对象返回 const_iterator。
iterator 可以转换为 const_iterator,反之则不行。
auto 可以和 being 、end结合使用,结果依赖于容器类型。
不需要写时,使用 cbegin 和 cend。