C++标准库提供了多种容器,分为序列容器、关联容器、无序关联容器、容器适配器及其他相关类型。以下是所有标准容器的分类及简要说明:
1. 序列容器(Sequence Containers)
按线性顺序存储元素,支持随机或顺序访问。
-
vector
-
动态数组,内存连续,支持快速随机访问。
-
优点:尾部插入/删除高效;
-
缺点1: 中间操作较慢; 缺点2: 因为是动态调整大小,存在元素增加时候,当数组空间不够了会进行重新进行内存分配,并进行批量数据拷贝。
-
适用场景:需频繁进行尾部操作场景; 如果需求是频繁尾部操作,又要结合中间删除添加,可以考虑vector+map结合使用。
-
-
deque
-
双端队列,支持头尾快速插入/删除;内部通过多个内存块方式实现,头部和中间操作优于vector;
-
随机访问性能接近
vector
,但内存非完全连续。 -
适用场景:需频繁头尾操作。
-
-
list
-
双向链表,任意位置插入/删除高效(O(1))。
-
不支持随机访问,需顺序遍历。
-
适用场景:频繁中间插入/删除,无需随机访问。
-
-
forward_list
(C++11)-
单链表,仅支持单向遍历,内存占用比
list
更小。 -
适用场景:内存敏感场景,只需单向遍历。
-
-
array
(C++11)-
固定大小数组,替代传统数组,提供STL接口(如迭代器)。
-
内存连续,大小不可变。
-
适用场景:需固定大小的数组。
-
-
string
-
存储字符序列,类似
vector<char>
,但专为字符串优化。 -
支持字符串操作(如拼接、查找子串)。
-
适用场景:文本处理。
-
2. 关联容器(Associative Containers)
基于红黑树实现,元素按键有序存储(默认升序)。
7. set
-
存储唯一键的有序集合,键即值。
-
适用场景:去重、有序唯一元素集合。
8.multiset
-
类似
set
,但允许重复键。 -
适用场景:有序但允许重复的集合。
9.map
-
存储键值对(
pair<const Key, Value>
),键唯一且有序。 -
适用场景:键到值的映射(如字典)。
10.multimap
-
类似
map
,但允许重复键。 -
适用场景:一键对应多个值(如电话簿同名条目)。
3. 无序关联容器(Unordered Associative Containers)(C++11)
基于哈希表实现,元素无序存储,依赖哈希函数。
11. unordered_set
- 哈希集合,键唯一,插入/查找平均 O(1)。
- 适用场景:快速存在性检查,无需排序。
12.unordered_multiset
-
类似
unordered_set
,但允许重复键。 -
适用场景:去重需求低,需快速插入/查找。
13.unordered_map
-
哈希键值对,键唯一。
-
适用场景:快速键值映射(如缓存)。
14.unordered_multimap
-
类似
unordered_map
,但允许重复键。 -
适用场景:一键多值哈希表。
4. 容器适配器(Container Adaptors)
基于其他容器实现的特定接口,提供受限功能。
15. stack
- 后进先出(LIFO),默认基于 deque
。
- 适用场景:函数调用栈、撤销操作。
16.queue
-
先进先出(FIFO),默认基于
deque实现;也可以基于list实现
-
适用场景:任务队列、消息缓冲。
17.priority_queue
-
元素按优先级排序,默认基于
vector
实现堆结构。 -
适用场景:任务调度(如最高优先级任务优先处理)。
5. 其他容器相关类型
18.bitset
-
固定大小的位集合,支持位操作(如与、或、位移)。
-
适用场景:标志位管理、位掩码。
19.valarray
-
数值数组,支持向量化数学运算(如逐元素加减)。
-
适用场景:高性能数值计算(较少使用)。
总结
-
标准容器总数:17个(序列6 + 关联4 + 无序4 + 适配器3)
-
其他类型:
bitset
和valarray
通常不归类为通用容器。 -
关联容器和无序关联容器说明:内部存储上一个使用红黑树一个使用hash存储;因此在选择上需要综合考虑,不需要顺序的,且规格不大的建议用无序关联容器,提升查询效率,如果规格过大,一般在k及其MB级别以上的条目,建议使用关联容器。
选择建议
-
数据量较大,且需要频繁进行访问:
set
、map
。 -
数据量适中,需要频繁进行访问,无顺序要求的,建议使用:
unordered_set和unordered_map
-
经常需要在头部和尾部进行插入删除的:deque。
-
经常需要在尾部进行操作的,建议使用:vector;
-
注意vector,list,array,queue,deque都不适合进行中间查找,如果既需要频繁头尾操作,又需要进行中间节点的操作,需要再结合map或set使用。