C++ STL 容器体系概览
STL(Standard Template Library)提供了丰富的容器类型,主要分为序列容器、关联容器和容器适配器三大类。理解它们的底层实现与内存管理机制,是编写高性能 C++ 代码的关键。
序列容器
std::vector:动态数组
vector 是最常用的序列容器,基于连续内存块存储元素,支持高效的随机访问。
底层结构与内存管理
- 连续内存:元素在内存中紧密排列,利于 CPU 缓存命中。
- 三指针逻辑:典型实现维护
begin_ptr(起始)、size_ptr(当前末尾)、capacity_ptr(容量末尾)三个指针。 - 扩容策略:当尾部空间不足时,会分配新内存(通常翻倍),迁移数据后释放旧内存。此过程涉及均摊 O(1) 的时间复杂度。
操作特性
| 场景 | 操作步骤 | 时间复杂度 |
|---|---|---|
| 尾部插入 | 构造元素并移动 size 指针 | O(1) |
| 空间不足扩容 | 分配新内存、迁移数据、释放旧内存 | 均摊 O(1) |
| 中间插入 | 移动后续元素腾出空间 | O(n) |
| 尾部删除 | 销毁元素并前移 size 指针 | O(1) |
| 中间删除 | 销毁目标并覆盖空隙 | O(n) |
注意:vector 不自动缩容,erase 不会释放多余内存。若需手动释放,可使用 shrink_to_fit() 或 vector<int>().swap(v)。扩容或中间插入/删除会导致迭代器失效。
std::deque:双端队列
double-ended queue 支持两端高效插入和删除,底层采用分段连续存储结构。
- 内存布局:由多个固定大小的数组块组成,通过中央控制映射器维护指针数组。
- 优势:逻辑上连续,物理上非连续。头尾操作均为 O(1),随机访问也是 O(1)。
- 适用场景:需要频繁在头部和尾部进行操作的场景,如 BFS 算法中的队列实现。
std::list:双向链表
每个元素存储在独立节点中,包含数据及前后指针。
- 内存管理:每个节点独立分配,高频操作可能产生内存碎片。
- 迭代器稳定性:插入或删除操作不会使其他迭代器失效(除被删元素外),这是 list 相比 vector 的巨大优势。
- 特殊操作:
splice()可在 O(1) 时间内将其他链表的元素移动到当前链表。
std::forward_list:单向链表
C++11 引入,仅支持前向遍历,节省了一个指针的内存开销。
- 特点:节点结构更紧凑,但无法反向遍历。使用
before_begin()获取首元素前的虚拟节点迭代器以支持头部插入。
std::array:固定大小数组
封装原生数组,编译期确定大小,无额外开销。

