当然可以!以下是 **C++ STL 中 `set` 的详细介绍和使用方法大全**,包括: --- ## 🧱 1. 基本概念 `std::set` 是一个 **有序集合**,底层实现是 **红黑树(RB-tree)**。 特点如下: * 所有元素 **自动升序排列(默认 `<`)** * 所有元素 **唯一**,不能重复 * 元素类型必须支持 `<` 操作符(可自定义) * **查找、插入、删除**操作都是 **O(log n)** 的时间复杂度 --- ## 📦 2. 头文件 ```cpp #include ``` --- ## 🧪 3. 声明与初始化 ```cpp std::set s1; // 空集合 std::set s2 = {4, 1, 3}; // 初始化,自动排序去重 std::set s3{"apple", "banana"}; std::set> s4; // 降序排列 ``` --- ## 🧾 4. 常用成员函数汇总 | 函数 | 作用 | | ------------------ | -------------------------------- | | `insert(val)` | 插入元素(成功返回 pair\) | | `emplace(val)` | 就地构造元素,性能比 `insert` 更高 | | `find(val)` | 返回指向该元素的迭代器,找不到返回 `end()` | | `count(val)` | 返回该值的数量(对于 set 只能是 0 或 1) | | `erase(val)` | 删除指定元素 | | `erase(it)` | 删除指定迭代器处元素 | | `clear()` | 清空集合 | | `size()` | 元素个数 | | `empty()` | 是否为空 | | `begin(), end()` | 起始、结束迭代器 | | `lower_bound(val)` | 第一个 `>= val` 的位置 | | `upper_bound(val)` | 第一个 `> val` 的位置 | | `equal_range(val)` | 返回一个 pair,表示 `[lower, upper)` 区间 | --- ## 🔨 5. 插入与查找示例 ```cpp std::set s; s.insert(5); s.insert(3); s.insert(8); s.insert(3); // 自动忽略重复 // 查找 if (s.find(3) != s.end()) { std::cout << "Found 3\n"; } // 遍历 for (int x : s) std::cout << x << " "; // 输出:3 5 8 ``` --- ## ⛏ 6. 删除元素 ```cpp s.erase(5); // 删除值为5的元素 auto it = s.find(8); if (it != s.end()) s.erase(it); // 用迭代器删除 ``` --- ## ⏬ 7. 自定义排序规则 ```cpp struct MyCmp { bool operator()(const int &a, const int &b) const { return a > b; // 降序 } }; std::set s = {1, 5, 3}; // 输出顺序:5 3 1 ``` --- ## 🌈 8. 自定义结构体作为元素 ### ✅ 正确写法:重载 `<` ```cpp struct Person { std::string name; int age; bool operator<(const Person &other) const { return age < other.age; // 按 age 排序 } }; std::set people; people.insert({"Tom", 25}); people.insert({"Jerry", 20}); ``` --- ## 🔄 9. 遍历方式 ```cpp // 方法1:范围 for for (int x : s) std::cout << x << " "; // 方法2:迭代器 for (auto it = s.begin(); it != s.end(); ++it) std::cout << *it << " "; ``` --- ## 🧵 10. lower\_bound / upper\_bound 示例 ```cpp std::set s = {2, 4, 6, 8}; auto lb = s.lower_bound(5); // 指向6 auto ub = s.upper_bound(6); // 指向8 ``` --- ## 🪄 11. set 和 multiset 区别 | 容器 | 是否允许重复 | 底层实现 | | ---------- | ------- | ---- | | `set` | ❌ 不允许重复 | 红黑树 | | `multiset` | ✅ 允许重复 | 红黑树 | --- ## 📚 12. 常见用法技巧 ### 用 set 去重: ```cpp std::vector v = {1, 2, 2, 3}; std::set s(v.begin(), v.end()); // 自动去重 ``` ### 用 set 排序: ```cpp std::set s = {5, 1, 3}; // 自动升序排列:1 3 5 ``` ### 交换两个 set: ```cpp std::set a = {1, 2}; std::set b = {3, 4}; a.swap(b); ``` --- ## 🧮 13. 高级操作(C++17 起) ```cpp if (auto [it, ok] = s.insert(10); ok) { std::cout << "插入成功:" << *it << "\n"; } ``` --- ## 🚨 14. 注意事项 * `insert` 不会覆盖已有元素,若想更新值,请先 `erase()` 再 `insert()` * 遍历时 **不要修改元素值**(因为会破坏红黑树结构) * `set` 的 `[]` 操作符不存在(不同于 `map`) --- 如需,我还可以为你提供: * 📘 set 应用实战代码示例 * 🧠 使用场景解析(如 top-k、排名、自动去重等) * 🧩 `unordered_set` 的比较与选择策略 是否要我继续讲 `multiset` 和 `unordered_set`?