📌 C++ STL 关联容器速查笔记(map / set / unordered / multi)

一句话记住分类

  • unordered → 无序(哈希表)
  • multi → 允许重复键
  • 不带 multi → 键唯一
  • map 存键值对,set 只存键(元素即键)

一、六大核心容器对比

容器 是否有序 键是否唯一 存储内容 底层实现 查找复杂度
map ✅ 是 ✅ 唯一 pair<const K, V> 红黑树 O(log n)
set ✅ 是 ✅ 唯一 K 红黑树 O(log n)
multimap ✅ 是 ❌ 可重复 pair<const K, V> 红黑树 O(log n)
multiset ✅ 是 ❌ 可重复 K 红黑树 O(log n)
unordered_map ❌ 否 ✅ 唯一 pair<const K, V> 哈希表 平均 O(1)
unordered_set ❌ 否 ✅ 唯一 K 哈希表 平均 O(1)

💡 unordered_multimap / unordered_multiset 用法类似,但较少使用。


二、std::map 基本操作(键值对 + 有序 + 唯一键)

#include <bits/stdc++.h>
using namespace std;

int main() {
    map<string, int> m;

    // 🔹 增
    m.insert({"A", 90});           // 花括号初始化
    m.insert(pair<string, int>{"B", 91});
    m.emplace("C", 85);            // 高效构造
    m["D"] = 95;                   // 不存在则插入,存在则修改

    // 🔹 查 & 改
    auto it = m.find("A");
    if (it != m.end()) {
        cout << "A: " << m["A"] << "\n";     // 通过键访问/修改
        m["A"] = 89;
        cout << it->first << ":" << it->second << "\n"; // 通过迭代器
        it->second = 88;
    }

    // 🔹 删
    auto it2 = m.find("B");
    auto next_it = m.erase(it2);   // 返回下一个迭代器
    cout << next_it->first << ":" << next_it->second << "\n";

    if (m.erase("C"))              // 按 key 删除,返回 0/1
        cout << "删除成功\n";

    // 🔹 遍历(自动按 key 升序)
    for (const auto& [k, v] : m)   // C++17 结构化绑定
        cout << k << ":" << v << "\n";
}

三、std::set 基本操作(仅键 + 有序 + 唯一键)

#include <bits/stdc++.h>
using namespace std;

int main() {
    set<string> s;

    // 🔹 增
    s.insert("A");
    string b = "B";
    s.insert(b);
    s.emplace("C");                // 高效构造
    s.emplace(string("D"));

    // 🔹 查 & “改”
    auto it = s.find("A");
    if (it != s.end()) {
        cout << "找到: " << *it << "\n";  // 解引用得值
        // ❌ *it = "AA"; // 编译错误!元素是 const
        s.erase(it);                    // ✅ 先删
        s.insert("AA");                 // ✅ 再插(逻辑更新)
    }

    // 🔹 删
    auto it2 = s.find("B");
    auto next_it = s.erase(it2);   // 返回下一个迭代器
    cout << *next_it << "\n";

    if (s.erase("C"))              // 按值删除,返回 0/1
        cout << "删除成功\n";

    // 🔹 遍历(自动字典序)
    for (const auto& x : s)
        cout << x << "\n";
}

四、一句话选择指南

  • 需要 键值对 + 快速查找 → unordered_map
  • 需要 键值对 + 有序遍历 → map
  • 需要 去重 + 快速判断存在 → unordered_set
  • 需要 去重 + 有序集合 → set
  • 允许重复键?→ 加 multi 前缀

更多推荐