4.5 KiB
4.5 KiB
当然可以!以下是 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
的比较与选择策略
是否要我继续讲 multiset
和 unordered_set
?