卡码笔记-最强八股文
首页
计算机基础
C++
Java
Go
🔥大模型🔥
  • 大模型面经
  • Java面经
  • C++面经
简历专栏
代码随想录 (opens new window)
首页
计算机基础
C++
Java
Go
🔥大模型🔥
  • 大模型面经
  • Java面经
  • C++面经
简历专栏
代码随想录 (opens new window)
  • 本栏必读

    • 关于本专栏
    • C++学习路线
    • C++面试题系优化
  • 基础与语法

  • 面向对象

  • STL 与容器

    • STL容器了解哪些
      • 简要回答
      • 详细回答
      • 知识拓展
    • STL中allocator的作用
    • STL中迭代器失效的场景
    • c++的map和unordered_map有什么区别和实现原理
    • map,deque,list的底层实现原理
    • unordered_map的rehash机制
    • vector底层原理和扩容过程
    • push_back()和emplace_back()的区别
  • 内存管理

  • C++11 与现代 C++

  • 智能指针

  • 并发与 I/O

# STL 容器的分类与选型

面试官问"STL 容器了解哪些",如果只是列名字,没有区分度。这道题的关键是把三大分类的底层结构差异和选型依据讲清楚——什么场景用什么容器,为什么。

# 简要回答

STL 容器分三大类加一类适配器:

顺序容器:vector(动态数组)、deque(分段数组)、list(双向链表)、forward_list(单向链表)、array(固定数组)。元素按插入顺序排列。

关联容器:map/multimap、set/multiset。底层红黑树,元素自动有序,操作 O(log n)。

无序容器:unordered_map/unordered_multimap、unordered_set/unordered_multiset。底层哈希表,无序,平均 O(1)。

容器适配器:stack、queue、priority_queue。不是独立容器,是对底层容器的接口封装。

# 详细回答

顺序容器——按插入顺序存储

核心区别在于内存布局和操作效率:

  • vector:连续内存,随机访问 O(1),尾部插入均摊 O(1),中间插入 O(n)。最常用,缓存友好。
  • deque:分段连续,两端插入 O(1),随机访问 O(1),中间插入 O(n)。适合两端都要操作的场景。
  • list:双向链表,任意位置插入/删除 O(1)(已知位置),不支持随机访问。迭代器不失效。
  • forward_list:单向链表,比 list 省一个指针的空间,只能单向遍历。
  • array:编译期固定大小,零开销替代 C 数组,不能扩容。

关联容器——自动有序

底层都是红黑树,键自动排序:

  • map:键值对,键唯一。需要有序遍历或范围查询时用。
  • set:只存键,自动去重排序。需要判断元素是否存在且要有序时用。
  • multimap/multiset:允许重复键。

无序容器——哈希查找

底层哈希表,不保证顺序:

  • unordered_map:键值对,平均 O(1) 查找/插入。只需要快速查找不需要有序时用。
  • unordered_set:只存键,平均 O(1) 判断存在性。

容器适配器——接口封装

  • stack:后进先出,默认底层是 deque。
  • queue:先进先出,默认底层是 deque。
  • priority_queue:堆,默认底层是 vector。

快速选型决策

需求 推荐容器
随机访问 + 尾部增删 vector
两端频繁增删 deque
中间频繁增删(已知位置) list
有序键值查找/范围查询 map
快速查找(不需要有序) unordered_map
去重 + 有序 set
去重 + 快速判断存在 unordered_set

STL容器分类

# 知识拓展

Q:vector 和 deque 怎么选?

默认用 vector。只有当需要频繁在头部插入/删除时才考虑 deque。vector 内存完全连续,缓存性能更好,且可以用 data() 拿裸指针传给 C API。deque 做不到这两点。

Q:map 和 unordered_map 怎么选?

需要有序(范围查询、按序遍历)用 map;只需要快速查找用 unordered_map。数据量小时 map 可能更快(红黑树常数小),数据量大时 unordered_map 优势明显。

Q:什么时候用 list?

现代 C++ 中 list 的使用场景很少。只有两种情况值得用:一是需要在中间频繁插入/删除且已持有迭代器;二是需要插入/删除后其他迭代器不失效。其他场景 vector 几乎总是更快(缓存局部性优势太大)。

Q:容器适配器和容器有什么区别?

适配器不是独立的数据结构,只是限制了底层容器的接口。stack 禁止随机访问只暴露 push/pop/top,底层默认是 deque 但可以换成 vector 或 list。适配器的意义是语义约束——告诉使用者"这里只能后进先出"。

Last Updated: 5/25/2026, 3:50:35 PM

← C++如何实现一个单例模式? STL中allocator的作用 →

评论

验证登录状态...

侧边栏 侧边栏
夜间模式 夜间
卡码简历 卡码简历
代码随想录 代码随想录
卡码投递表 卡码投递表🔥
2026实习校招群 2026群
添加客服微信 2026实习校招客服微信 PS:通过微信后,请发送姓名-学校-年级-2026实习/校招
支持卡码笔记 支持卡码笔记
鼓励/支持/赞赏Carl 卡码笔记赞赏码
1. 如果感觉本站对你很有帮助,也可以请Carl喝杯奶茶,金额大小不重要,心意已经收下
2. 希望大家都能梦想成真,有好的前程,加油💪