C++学习:set

本文介绍了C++标准库中的set,multiset和unordered_set容器,包括它们的定义、特点(如排序规则、唯一性、时间复杂度),以及如何通过自定义比较函数和操作(如插入、查找、移除)来使用这些容器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.set集合

set是一种容器,用于存储一组唯一的元素,并按照一定的排序规则进行排序。set中的元素是按照升序排序的,默认情况下它使用元素的比较运算符(<)来进行排序。

set的定义和结构如下:

template<class Key, class Compare = less<Key>,
class Allocator =allocator<Key>>
class set;

·Key:表示存储在set中的元素的类型。
·Compare:表示元素之间的比较函数对象的类型,默认为less,即按照元素的值进行比较
·Allocator:表示用于分配内存的分配器类型,默认为allocator。
set的内部实现使用了红黑树(一种自平衡的二叉搜索树)来存储元素,并保持元素的有序性这使得在set中插入、删除和查找元素的时间复杂度都是对数时间,即O(log n)。
set中的元素是唯一的,即不允许重复的元素存在。当插入一个重复的元素时,set会自动忽略该元素。

image-20240219202331018 image-20240219202346421

修改比较顺序的常用办法:

//方法1
#include <iostream>
#include <set>
using namespace std;
int main(){
	set<int, greater<int>> mySet;
mySet.insert(25);
mySet.insert(17);
mySet.insert(39);
mySet.insert(42);
for(const auto& elem :myset)
{
cout<< elem<<" ";
}
cout << endl;
return 0;
}

//方法2
#include <iostream>
#include <set>
using namespace std;
struct MyCompare {
	bool operator()(const int& a, const int& b)const {
        // 自定义比较逻辑
        return a>b; 
        // 改为逆序
};
int main(){	
	set<int, MyCompare> mySet;
	mySet.insert(25);
    mySet.insert(17);
    mySet.insert(39);
    mySet.insert(42);
for(const auto& elem : mySet)
{
    cout<< elem<< " ";
}
cout<< endl;
return 0;}

multiset多重集合

multiset是一种容器,它与set类似,用于存储一组元素,并按照一定的排序规则进行排序。
不同之处在于,multiset容器允许存储重复的元素。

image-20240219202947869 image-20240219203000660

PS:使用st.erase(x)会把全部x删除
如果只想删除一个:st.earse(st.find(x));

3.unordered_set无序集合

unordered_set是一种容器,用于存储一组唯一的元素,并且没有特定的顺序。unordered_set容器使用哈希表来实现元素的存储和访问,因此元素的插入、删除和查找的时间复杂度都是常数时间,即0(1)。
unordered_set中的元素是唯一的,即不允许重复的元素存在。当插入一个重复的元素时,unordered_set会自动忽略该元素。
image-20240219203418165

这些时间复杂度是基于哈希函数的性能和哈希冲突的情况来计算的。平均情况下,unordered_set的插入、查找和移除操作都具有常数时间复杂度O(1)。然而,在最坏情况下这些操作的时间复杂度可能为O(n),其中n是无序集合中的元素数量。最坏情况通常发生在哈希冲突较为严重的情况下,导致需要线性探测或链式解决冲突,从而影响性能。所以我们一般情况下不会使用unordered_set,而选择使用复杂度更稳定的set。

4.代码示例

#include <iostream>
#include <set>
using namespace std;
int main() {
	set<int> mySet;
	// 插入元素
	mySet.insert(5);
	mySet.insert(2);
	mySet.insert(8);
	mySet.insert(2);
	//重复元素
	// 遍历集合
	cout << "Set elements:";
		for (const auto& elem : mySet) {
			cout << elem << " ";
		}
	cout << endl;
	// 查找元素
	int searchValue = 5;
	auto it = mySet.find(searchValue);
	if (it != mySet.end()) {
		cout << searchValue << " found in the set." << endl;
	}
	else {
		cout << "searchValue" << " not found in the set." << endl;
	}

	return 0;
}

!!!

auto it = mySet.find(searchValue);:
使用 find 函数在 mySet 中搜索值为 searchValue 的元素。find 返回一个迭代器,指向找到的元素,如果找不到,则返回 mySet.end()

// 移除元素
	int removeValue = 2;
	mySet.erase(removeValue);
// 再次遍历集合
	cout<<"Set elements after removal:";
	for(const auto& elem : mySet){
	cout<< elem<< " ";
	}
	cout<< endl;
// 清空集合
	mySet.clear();
// 检查集合是否为空
	if(mySet.empty()){
	cout<<"Set is empty."<< endl;} 
	else {
	cout<<"Set is not empty."<< endl;}
	
	return 0;}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值