STL 容器分類概覽
| 類別 | 容器 | 底層結構 | 核心特點 | 典型場景 |
| 序列容器 | vector | 動態數組 | 隨機訪問 O(1),尾部增刪 O(1) 攤還,中間增刪 O(n) | 首選容器,需快速隨機訪問 |
| deque | 雙端隊列 (分段連續) | 雙端增刪 O(1),隨機訪問 O(1),中間增刪 O(n) | 需雙端操作,或大對象避免 vector 擴容拷貝 |
| list | 雙向鏈表 | 任意位置增刪 O(1),無隨機訪問,內存分散 | 頻繁中間增刪,不需隨機訪問 |
| 容器適配器 | stack | 默認 deque | LIFO,僅 top/push/pop/empty/size,無迭代器 | 函數調用棧、表達式求值、DFS |
| queue | 默認 deque | FIFO,front/back/push/pop/empty/size,無迭代器 | BFS、任務調度、緩衝區 |
| 關聯容器 | set/multiset | 紅黑樹 | 有序、唯一/允許重復,查找/增刪 O(log n) | 去重、有序集合、區間查詢 |
| map/multimap | 紅黑樹 | 鍵值對、按鍵有序、唯一/允許重復鍵,查找/增刪 O(log n) | 字典、鍵值映射、統計頻次 |
序列容器詳解與代碼示例
1. vector - 動態數組
#include <vector> <iostream>
using namespace std;
int main() {
vector v;
// 插入
for (int i=0; i<10; ++i) v.push_back(i);
// 遍歷 (三種方式)
for (auto it=v.begin(); it!=v.end(); ++it) cout << *it << ' ';
for (int x : v) cout << x << ' '; // C++11 範圍 for
for (size_t i=0; i v1(v);
return 0;
}
2. deque - 雙端隊列
#include <deque>
deque q;
q.push_front(3); q.push_back(5); q.push_front(11); // 11 3 5
cout << q.at(2) << ' ' << q.front() << ' ' << q.back() << ' ' << q[1]; // 5 11 5 3
3. list - 雙向鏈表
#include <list>
list l;
l.push_front(12); l.push_front(13); l.push_back(99); // 13 12 99
for (auto x : l) cout << x << ' ';
cout << "\nsize: " << l.size() << ", front: " << l.front() << ", back: " << l.back();
// 注意:list 無 operator[]、at(),不支持隨機訪問
容器適配器
4. stack - 先進後出 (LIFO)
#include <stack>
stack s;
s.push(12); s.push(15); s.push(55);
while (!s.empty()) { cout << s.top() << ' '; s.pop(); } // 55 15 12
// 無迭代器,無法遍歷不彈出
5. queue - 先進先出 (FIFO)
#include <queue>
queue q;
q.push(3); q.push(6); q.push(9);
while (!q.empty()) { cout << q.front() << ' '; q.pop(); } // 3 6 9
關聯容器
6. set/multiset - 有序集合
#include <set>
set s; // 自動排序、去重
s.insert({11, 1, 22, 66, 88}); // 1 11 22 66 88
// multiset 允許重復元素
// 區間查詢利器
auto it_low = s.lower_bound(22); // 首個 ≥ 22
auto it_up = s.upper_bound(22); // 首個 > 22
auto range = s.equal_range(22); // pair
7. map/multimap - 鍵值映射
#include <map>
map m; // key 自動排序、唯一
m.insert({{1,10}, {2,20}, {3,30}});
// multimap 允許相同 key
for (auto& [k, v] : m) // C++17 結構化綁定
cout << "key: " << k << ", value: " << v << endl;
// 或傳統迭代器
for (auto it=m.begin(); it!=m.end(); ++it)
cout << it->first << " => " << it->second << endl;
迭代器失效規則速查 (面試必考)
| 容器 | 操作 | 迭代器失效情況 |
| vector | insert/push_back | 若擴容則全部失效,否則插入點及之後失效 |
| vector | erase | 被刪除點及之後失效 |
| deque | insert/erase | 除首尾操作外,全部失效 |
| list | insert/erase | 僅被刪除元素迭代器失效,其他穩定 |
| set/map | insert/erase | 僅被刪除元素迭代器失效,其他穩定 |
選型決策樹
- 需要鍵值映射 →
map / unordered_map (無序更快)
- 需要唯一性/有序集合 →
set / unordered_set
- 需要棧/隊列語義 →
stack / queue
- 需隨機訪問且主要尾部操作 →
vector (默認首選)
- 需雙端操作或大對象避免拷貝 →
deque
- 需頻繁中間增刪、不需隨機訪問 →
list (現代 C++ 中較少用,常被 vector/deque 替代)
現代 C++ 實戰技巧
- 預留容量:
v.reserve(10000) 避免多次擴容拷貝。
- 縮容釋放:
v.shrink_to_fit() (C++11) 釋放多餘容量。
- 原地構造:
v.emplace_back(args...) 避免臨時對象拷貝/移動。
- 異構查找 (C++14):
map.find(key, less{}) 透明比較器避免構造 key 對象。
- 節點提取/插入 (C++17):
map.extract() / insert(node) 無拷貝移動節點所有權。
熟練掌握各容器特性、迭代器失效規則、現代 API,是高效使用 STL 的關鍵。