STL功能与使用
C++ STL 容器入门与速查
C++ 标准库提供了常用容器和算法。选择容器时先想清楚需要什么:按下标访问、先进先出、自动排序、键值查找,还是只需要快速平均查找。
1. 常见容器如何选择
| 容器 | 主要特点 | 常见操作的复杂度 |
|---|---|---|
vector |
连续动态数组,支持下标访问 | 尾部插入均摊 O(1),中间插入/删除 O(n) |
stack |
后进先出 | 栈顶操作 O(1) |
queue |
先进先出 | 队首、队尾操作 O(1) |
set / multiset |
有序集合;前者去重,后者允许重复 | 查找、插入、删除 O(log n) |
priority_queue |
每次取出优先级最高的元素 | 查看堆顶 O(1),插入/弹出 O(log n) |
map |
按键排序的键值对 | 查找、插入、删除 O(log n) |
unordered_map |
哈希表,不保证遍历顺序 | 平均 O(1),最坏可能 O(n) |
2. vector
适合需要按下标访问的序列。元素连续存放,v[i] 是 O(1);使用 at(i) 会进行边界检查。
1 | |
插入或删除可能使指向 vector 元素的迭代器、指针和引用失效。具体失效范围取决于操作位置和是否重新分配内存;修改后不要继续使用可能失效的迭代器。
3. stack 和 queue
1 | |
pop() 只移除元素,不返回元素值;读取前应确认容器非空。队列还可用 back() 查看队尾。
4. set 和 multiset
两者默认按升序维护元素。set 不允许重复值,multiset 允许重复值。
1 | |
对于有序容器,lower_bound(x) 返回第一个大于等于 x 的位置,upper_bound(x) 返回第一个大于 x 的位置。迭代器可能等于 end(),解引用前必须检查。
5. priority_queue
默认是大根堆,top() 返回最大元素。用 greater<int> 可以创建小根堆:
1 | |
堆只保证堆顶是当前优先级最高的元素,不支持遍历时按完整顺序访问。
6. map 和 unordered_map
两者都保存键值对。map 按键排序;unordered_map 使用哈希,遍历顺序不确定。
1 | |
使用 m[key] 读取一个不存在的键时,会插入该键并创建默认值。若只想查找、不想插入,使用 find。C++17 可以用结构化绑定遍历:
1 | |
7. 标准算法与常见误区
find、sort、reverse 和 lower_bound 等是 <algorithm> 中的算法,不是 vector 的成员函数。lower_bound 要求输入范围已经按相同规则排序。
vector::reverse()不存在,应写reverse(v.begin(), v.end())。find对vector是线性查找;需要频繁查找时可考虑set或哈希表。set是有序的;unordered_map才是不保证顺序。priority_queue<int>默认取最大值;小根堆需要指定比较器。- 容器的复杂度通常指常见或平均情况,遇到性能要求时应结合操作和数据规模判断。
可以从牛客 130 系列中挑选题目练习。每次使用容器时,先确认需要的操作,再选合适的数据结构。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 GuMing的殿堂!
评论


