C++ 标准模板库(STL)是 C++ 语言的基石之一,它提供了一套性能卓越、经过严格测试的通用算法和数据结构。其中,容器是 STL 最核心的部分,它们是用于管理和存储对象集合的类模板。正确地选择容器,不仅能让代码更简洁、更安全,还能显著提升程序的性能。
本文将全面介绍 C++ 中常见的各类容器,分析它们的内部实现、优缺点以及最佳适用场景,帮助你今后在项目开发中做出明智的选择。
C++ 容器主要可以分为三类:顺序容器、关联容器和无序关联容器。
顺序容器中的元素按照严格的线性顺序排列。你可以精确地控制每个元素的位置。
std::vector
[]
或 .at()
进行随机访问的时间复杂度为 O(1),并且由于内存连续,能很好地利用 CPU 缓存。.push_back()
, .pop_back()
)的平均时间复杂度为 O(1)。vector
容量不足时,它会重新分配一块更大的内存,并将所有旧元素拷贝过去,这可能是一个耗时的操作。std::deque
(Double-Ended Queue)vector
(需要两次指针解引用),但时间复杂度仍为 O(1)。vector
类似,中间操作的时间复杂度为 O(n)。vector
,遍历速度可能稍慢。std::list
list[i]
)访问元素。要访问第 n 个元素,必须从头或尾开始遍历 n 次,时间复杂度为 O(n)。std::array
(C++11)关联容器根据键 (key) 来高效地排序和存储元素。它们非常适合用于快速查找。
std::map
std::set
map
一样,内部也是由红黑树实现,元素自动排序。
std::multimap
和std::multiset
分别是map
和set
的多键版本,它们允许存储重复的键。
这类容器在 C++11 中引入,它们也存储键或键值对,但基于哈希表 (Hash Table) 实现,不保证元素有序,换来的是更快的平均性能。
std::unordered_map
std::map
的常用高性能替代品。std::unordered_set
为了方便选择,下表总结了各类容器的特点:
需求 | 推荐容器 | 备选方案 | 时间复杂度 (平均) |
---|---|---|---|
快速随机访问 | std::vector | std::deque , std::array | O(1) |
大量中间插入/删除 | std::list | std::forward_list | O(1) |
快速两端插入/删除 | std::deque | std::list | O(1) |
键值对存储 (有序) | std::map | std::multimap | O(log n) |
键值对存储 (最快查找) | std::unordered_map | std::unordered_multimap | O(1) |
存储唯一元素 (有序) | std::set | std::multiset | O(log n) |
存储唯一元素 (最快查找) | std::unordered_set | std::unordered_multiset | O(1) |
通用建议:
std::vector
通常是最好的第一选择。它的性能优秀且用途广泛。std::unordered_map
是 std::map
的高性能替代品。std::list
。