定义
std::set - cppreference.cn - C++参考手册
存储唯一的、经过排序的键(key)。set 内部通常基于平衡二叉搜索树(如红黑树)实现,这保证了高效的查找、插入和删除操作
- 唯一性:
set 中的每个元素(键)都是唯一的。尝试插入一个已存在的值会失败,容器保持不变 - 有序性:元素在容器中自动排序。默认按升序排列(使用
std::less) - 键即值:在
set 中,元素本身就是键。它不存储键值对(那是 map 的功能) - 平衡树实现:通常使用红黑树,保证了 O(log n) 的时间复杂度
- 不可变键:一旦元素插入
set,就不能直接修改其值,因为这会破坏排序。如果需要“修改”,必须先删除再插入新值
构造函数
1、默认构造函数
#include <iostream>
#include <set>
#include <random>
using namespace std;
int main()
{
system("chcp 65001");
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1, 10);
// 默认构造函数
std::set<int> set1;
for (int i = 1; i < 10; i++)
{
set1.insert(dis(gen));
}
cout << "set1.size()-> " << set1.size() << endl;
cout << "set1.empty()-> " << boolalpha << set1.empty() << endl;
for (auto it : set1)
{
cout << "set1-> " << it << endl;
}
}
2、带比较函数的构造函数
int main()
{
system("chcp 65001");
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1, 10);
std::set<int, std::greater<int>> set1;
for (int i = 1; i < 10; i++)
{
set1.insert(dis(gen));
}
cout << "set1.size()-> " << set1.size() << endl;
cout << "set1.empty()-> " << boolalpha << set1.empty() << endl;
for (auto it : set1)
{
cout << "set1-> " << it << endl;
}
}
3、区间构造函数
int main()
{
system("chcp 65001");
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1, 100);
std::array<int, 2> arr1 = { 222,333 };
std::set<int, std::greater<int>> set1(arr1.begin(), arr1.end());
for (int i = 1; i < 10; i++)
{
set1.insert(dis(gen));
}
cout << "set1.size()-> " << set1.size() << endl;
cout << "set1.empty()-> " << boolalpha << set1.empty() << endl;
for (auto it : set1)
{
cout << "set1-> " << it << endl;
}
}
4、初始列表构造函数
int main()
{
system("chcp 65001");
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1, 100);
std::set<int, std::greater<int>> set1 = { 1,3,8,1,5,78,5,6 };
for (int i = 1; i < 10; i++)
{
set1.insert(dis(gen));
}
cout << "set1.size()-> " << set1.size() << endl;
cout << "set1.empty()-> " << boolalpha << set1.empty() << endl;
for (auto it : set1)
{
cout << "set1-> " << it << endl;
}
}
5、拷贝构造函数
int main()
{
system("chcp 65001");
std::set<int, std::greater<int>> set2 = { 11,22,33 };
std::set<int, std::greater<int>> set1(set2);
cout << "set1.size()-> " << set1.size() << endl;
cout << "set1.empty()-> " << boolalpha << set1.empty() << endl;
for (auto it : set1)
{
cout << "set1-> " << it << endl;
}
}
6、移动构造函数
int main()
{
system("chcp 65001");
std::set<int, std::greater<int>> set2 = { 11,22,33 };
std::set<int, std::greater<int>> set1(std::move(set2));
cout << "set2.size()-> " << set2.size() << endl;
cout << "set2.empty()-> " << boolalpha << set2.empty() << endl;
cout << "set1.size()-> " << set1.size() << endl;
cout << "set1.empty()-> " << boolalpha << set1.empty() << endl;
for (auto it : set1)
{
cout << "set1-> " << it << endl;
}
}
迭代器
| 函数 | 描述 |
|---|
begin() / end() | 返回指向首元素和尾后位置的正向迭代器 |
rbegin() / rend() | 返回指向末元素和首前位置的反向迭代器 |
cbegin() / cend() | 返回常量正向迭代器 |
crbegin() / crend() | 返回常量反向迭代器 |
int main()
{
system("chcp 65001");
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1, 100);
std::set<int, std::greater<int>> set1;
for (int i = 1; i < 10; i++)
{
set1.insert(dis(gen));
}
cout << "set1.size()-> " << set1.size() << endl;
cout << "set1.max_size()-> " << set1.max_size() << endl;
cout << "set1.empty()-> " << boolalpha << set1.empty() << endl;
for (auto it : set1)
{
cout << "set1-> " << it << endl;
}
for (auto it = set1.begin(); it != set1.end(); it++)
{
cout << "begin-end-> " << *it << endl;
}
for (auto it = set1.cbegin(); it != set1.cend(); it++)
{
cout << "cbegin-cend-> " << *it << endl;
}
for (auto it = set1.rbegin(); it != set1.rend(); it++)
{
cout << "rbegin-rend-> " << *it << endl;
}
for (auto it = set1.crbegin(); it != set1.crend(); it++)
{
cout << "crbegin-crend-> " << *it << endl;
}
}
查找与计数
| 函数 | 描述 |
|---|
find(key) | 查找 key,返回指向它的迭代器;未找到返回 s.end() |
count(key) | 返回 key 在 set 中的数量(0 或 1) |
contains(key) | (C++20) 检查 key 是否存在于 set 中,返回 bool |
lower_bound(key) | 返回指向第一个不小于 key 的元素的迭代器 |
upper_bound(key) | 返回指向第一个大于 key 的元素的迭代器 |
equal_range(key) | 返回一个 std::pair,包含 lower_bound 和 upper_bound 的结果 |
int main()
{
system("chcp 65001");
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1, 100);
std::set<int, std::greater<int>> set1 = { 1,2,3 };
for (int i = 1; i < 10; i++)
{
set1.insert(dis(gen));
}
cout << "set1.size()-> " << set1.size() << endl;
cout << "set1.max_size()-> " << set1.max_size() << endl;
cout << "set1.empty()-> " << boolalpha << set1.empty() << endl;
auto it = set1.find(2);
if (it != set1.end())
{
cout << "set1.find(2)-> " << *it << endl;
}
cout << "set1.count(2))-> " << set1.count(2) << endl;
cout << "set1.contains(2))-> " << boolalpha << set1.contains(2) << endl;
it = set1.lower_bound(2);
if (it != set1.end())
{
cout << "set1.lower_bound(2)-> " << *it << endl;
}
it = set1.upper_bound(2);
if (it != set1.end())
{
cout << "set1.upper_bound(2)-> " << *it << endl;
}
auto pair = set1.equal_range(2);
for (auto it = pair.first; it != pair.second; ++it) {
std::cout << "equal_range-> " << *it << endl;
}
}
修改函数
| 函数 | 描述 |
|---|
insert(value) | 插入一个元素。返回 std::pair<iterator, bool>,bool 表示是否插入成功 |
insert(hint, value) | 提供插入位置的提示 hint,可能提高效率 |
emplace(args...) | 就地构造一个元素并插入。返回 std::pair<iterator, bool> |
erase(key) | 删除值为 key 的元素,返回删除的元素数量(0 或 1) |
erase(it) | 删除迭代器 it 指向的元素 |
erase(first, last) | 删除范围 [first, last) 的元素 |
clear() | 删除所有元素 |
swap(other) | 与另一个 set 交换内容 |
int main()
{
system("chcp 65001");
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1, 100);
std::set<int, std::greater<int>> set1 = { 1,2,3 };
for (int i = 1; i < 10; i++)
{
set1.insert(dis(gen));
}
set1.emplace(123);
cout << "set1.size()-> " << set1.size() << endl;
cout << "set1.max_size()-> " << set1.max_size() << endl;
cout << "set1.empty()-> " << boolalpha << set1.empty() << endl;
set1.erase(1);
set1.erase(set1.begin());
set1.erase(set1.begin(), --set1.end());
for (auto it : set1)
{
cout << "set1-> " << it << endl;
}
set1.clear();
}
其他
| 操作 | 时间复杂度 |
|---|
insert / emplace | O(log n) |
erase (键) | O(log n) |
erase (迭代器) | O(1) 摊销 (删除单个元素) |
find / count | O(log n) |
lower_bound / upper_bound | O(log n) |
size / empty | O(1) |
begin / end | O(1) |