C++容器set

定义

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_boundupper_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;

	// lower_bound
	it = set1.lower_bound(2);
	if (it != set1.end())
	{
		cout << "set1.lower_bound(2)-> " << *it << endl;
	}

	// upper_bound
	it = set1.upper_bound(2);
	if (it != set1.end())
	{
		cout << "set1.upper_bound(2)-> " << *it << endl;
	}

	// equal_range
	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 / emplaceO(log n)
erase (键)O(log n)
erase (迭代器)O(1) 摊销 (删除单个元素)
find / countO(log n)
lower_bound / upper_boundO(log n)
size / emptyO(1)
begin / endO(1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值