Files
Data-Structure/STL/STL-Set/README.MD
2025-08-06 18:43:00 +08:00

4.5 KiB
Raw Blame History

当然可以!以下是 C++ STL 中 set 的详细介绍和使用方法大全,包括:


🧱 1. 基本概念

std::set 是一个 有序集合,底层实现是 红黑树RB-tree。 特点如下:

  • 所有元素 自动升序排列(默认 <
  • 所有元素 唯一,不能重复
  • 元素类型必须支持 < 操作符(可自定义)
  • 查找、插入、删除操作都是 O(log n) 的时间复杂度

📦 2. 头文件

#include <set>

🧪 3. 声明与初始化

std::set<int> s1;                          // 空集合
std::set<int> s2 = {4, 1, 3};              // 初始化,自动排序去重
std::set<std::string> s3{"apple", "banana"};

std::set<int, std::greater<int>> s4;      // 降序排列

🧾 4. 常用成员函数汇总

函数 作用
insert(val) 插入元素(成功返回 pair<iterator, true>
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. 插入与查找示例

std::set<int> 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. 删除元素

s.erase(5);  // 删除值为5的元素
auto it = s.find(8);
if (it != s.end()) s.erase(it);  // 用迭代器删除

7. 自定义排序规则

struct MyCmp {
    bool operator()(const int &a, const int &b) const {
        return a > b;  // 降序
    }
};

std::set<int, MyCmp> s = {1, 5, 3};  // 输出顺序5 3 1

🌈 8. 自定义结构体作为元素

正确写法:重载 <

struct Person {
    std::string name;
    int age;

    bool operator<(const Person &other) const {
        return age < other.age;  // 按 age 排序
    }
};

std::set<Person> people;
people.insert({"Tom", 25});
people.insert({"Jerry", 20});

🔄 9. 遍历方式

// 方法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 示例

std::set<int> 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 去重:

std::vector<int> v = {1, 2, 2, 3};
std::set<int> s(v.begin(), v.end());  // 自动去重

用 set 排序:

std::set<int> s = {5, 1, 3};
// 自动升序排列1 3 5

交换两个 set

std::set<int> a = {1, 2};
std::set<int> b = {3, 4};
a.swap(b);

🧮 13. 高级操作C++17 起)

if (auto [it, ok] = s.insert(10); ok) {
    std::cout << "插入成功:" << *it << "\n";
}

🚨 14. 注意事项

  • insert 不会覆盖已有元素,若想更新值,请先 erase()insert()
  • 遍历时 不要修改元素值(因为会破坏红黑树结构)
  • set[] 操作符不存在(不同于 map

如需,我还可以为你提供:

  • 📘 set 应用实战代码示例
  • 🧠 使用场景解析(如 top-k、排名、自动去重等
  • 🧩 unordered_set 的比较与选择策略

是否要我继续讲 multisetunordered_set