Contents

Cpp常见STL操作

一、STL 容器整体分类(先有全局认知)

STL Containers
├── 顺序容器(Sequence)
│   ├── vector
│   ├── deque
│   ├── list / forward_list
│   └── array
│
├── 关联容器(有序,基于红黑树)
│   ├── set / multiset
│   └── map / multimap
│
├── 无序关联容器(哈希表)
│   ├── unordered_set / unordered_multiset
│   └── unordered_map / unordered_multimap
│
└── 容器适配器(接口受限)
    ├── stack
    ├── queue
    └── priority_queue

二、顺序容器(Sequence Containers)

1️⃣ vector —— 动态数组(最常用)

特点

  • 连续内存
  • 支持随机访问
  • 尾插效率高
vector<int> v;

v.push_back(10);          // 在末尾插入一个元素
v.emplace_back(20);       // 在末尾原地构造元素(避免拷贝)

v.pop_back();             // 删除末尾元素

v.insert(v.begin(), 5);   // 在指定位置插入元素
v.erase(v.begin());       // 删除指定位置的元素

v.clear();                // 清空所有元素(capacity 不变)

v.size();                 // 返回当前元素个数
v.empty();                // 判断是否为空

v.reserve(100);           // 预分配内存空间,不创建元素
v.resize(50);             // 调整元素个数(多的补默认值)

v[0];                     // 访问元素(不检查越界)
v.at(0);                  // 访问元素(越界抛异常)

v.front();                // 访问第一个元素
v.back();                 // 访问最后一个元素

sort(v.begin(), v.end());  // 排序

vector<int> sub_v(v.begin() + 2, v.begin() + 5); // 取下标 [2,5) 的子数组

典型场景

  • 任务列表
  • 数据缓存
  • 算法中 80% 的顺序存储需求

2️⃣ deque —— 双端队列

特点

  • 头尾插入删除都是 O(1)
  • 非连续内存
deque<int> dq;

dq.push_back(1);          // 在末尾插入元素
dq.push_front(2);         // 在头部插入元素

dq.pop_back();            // 删除末尾元素
dq.pop_front();           // 删除头部元素

dq[0];                    // 随机访问元素
dq.size();                // 当前元素数量
dq.empty();               // 是否为空

dq.insert(dq.begin() + 1, 3); // 在指定位置插入元素
dq.erase(dq.begin() + 1);      // 删除指定位置元素

dq.front();               // 访问第一个元素
dq.back();                // 访问最后一个元素

典型场景

  • BFS
  • 滑动窗口
  • 就绪队列(需要头尾操作)

3️⃣ list / forward_list —— 链表

特点

  • 任意位置插入/删除 O(1)
  • 不支持随机访问
list<int> lst;

lst.push_back(1);         // 在末尾插入元素
lst.push_front(2);        // 在头部插入元素

lst.insert(it, 3);        // 在迭代器位置插入元素
lst.erase(it);            // 删除迭代器指向的元素

lst.remove(5);            // 删除所有值为 5 的元素
lst.clear();              // 清空链表

lst.size();               // 元素数量

sort(lst.begin(), lst.end()); // 排序链表
lst.reverse();            // 反转链表

// 遍历链表
for (auto it = lst.begin(); it != lst.end(); ++it) {
    cout << *it << " ";
}

典型场景

  • 频繁中间插删
  • 对迭代器稳定性有要求的场景 (现代 C++ 中使用频率不高)

4️⃣ array —— 固定大小数组

特点

  • 大小编译期确定
  • 性能接近 C 数组
array<int, 5> arr;

arr[0];                   // 访问元素
arr.size();               // 返回固定大小
arr.fill(0);              // 所有元素赋值为 0
arr.begin();              // 指向第一个元素的迭代器
arr.end();                // 指向最后一个元素后面的迭代器
sort(arr.begin(), arr.end()); // 排序

三、关联容器(有序,红黑树实现)

5️⃣ set / multiset —— 有序集合

特点

  • 自动排序
  • 查找、插入、删除 O(log n)
set<int> s;

s.insert(3);              // 插入元素(自动排序,set 去重)
s.erase(3);               // 删除指定元素

s.find(3);                // 查找元素,返回迭代器
s.count(3);               // 元素个数(set 为 0 或 1)

s.begin();                // 指向最小元素
s.size();                 // 元素数量
s.empty();                // 是否为空

典型场景

  • 去重 + 有序
  • 区间、排名问题

6️⃣ map / multimap —— 有序键值映射

特点

  • key 自动排序
  • key → value 映射
map<int, int> mp;

mp[1] = 10;               // 插入或修改 key=1 的值
mp.insert({2, 20});       // 插入键值对

mp.find(1);               // 查找 key
mp.erase(1);              // 删除指定 key

mp.size();                // 键值对数量
mp.empty();               // 是否为空

典型场景

  • 有序字典
  • 需要按 key 顺序遍历

四、无序关联容器(哈希表)

7️⃣ unordered_set

特点

  • 平均 O(1) 查找
  • 元素无序
unordered_set<int> us;

us.insert(5);             // 插入元素
us.erase(5);              // 删除元素

us.find(5);               // 查找元素
us.count(5);              // 判断是否存在

us.reserve(100);          // 预分配桶,减少 rehash

8️⃣ unordered_map

unordered_map<int, int> um;

um[1] = 10;               // 插入或更新键值对
um.insert({2, 20});       // 插入键值对

um.find(1);               // 查找 key
um.erase(1);              // 删除 key

um.size();                // 键值对数量

典型场景

  • 高频查找
  • 不关心顺序

五、容器适配器(接口受限)

9️⃣ stack —— 栈(LIFO)

stack<int> st;

st.push(1);               // 入栈
st.pop();                 // 出栈(不返回值)
st.top();                 // 访问栈顶元素

st.size();                // 元素数量
st.empty();               // 是否为空

🔟 queue —— 队列(FIFO)

queue<int> q;

q.push(1);                // 入队
q.pop();                  // 出队
q.front();                // 访问队首元素
q.back();                 // 访问队尾元素

1️⃣1️⃣ priority_queue —— 优先队列(堆)

priority_queue<int> pq;   // 默认大顶堆

pq.push(3);               // 插入元素
pq.pop();                 // 删除优先级最高的元素
pq.top();                 // 获取优先级最高的元素

pq.size();                // 元素数量
pq.empty();               // 是否为空