定义
 
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) |