C++ STL中的无序集

时间:2020-02-23 14:30:08  来源:igfitidea点击:

C++标准模板库支持几种数据结构,这些数据结构在任何程序员的生活中都起着重要作用。
这样的数据容器之一就是" C++中的无序集"。
与STL集不同,这些类型的集在存储元素方面是无序的。

无序集的属性

以下是C++ STL中无序集的属性。

  • 唯一性–无序集中的每个元素都是唯一的。

  • 未索引-无序集合中的元素无法按位置索引,例如矢量和地图。

  • 不可变–我们无法修改或者更改无序集中的元素。
    集合仅支持其元素的添加和删除。

  • 内部实现–我们使用哈希表实现无序集

初始化无序集

有多种方法可以在C++中初始化无序集。

//For the usage of unordered set
#include<unordered_set>

//For input output
#include<iostream>
using namespace std;

int main(){

	//Method - 1
	//An empty unordered set of integers
	unordered_set<int> s1;

	//Method - 2	
	//Hard-coded unordered set
	unordered_set<int> s2 = {1, 4, 8, 3, 2};

	//Method - 3
	//Initializing an unordered set using another unordered set
	unordered_set<int> s4(s2);
	//s4 = {1, 4, 8, 3, 2}

	//Method - 4
	//Initializing an unordered set using arrays
	int arr[] = {6, 2, 4, 5, 1};
	unordered_set<int> s5(arr, arr+3);
	//s4 = {4, 2, 6}

}

第四种方法以相反的方式保存元素。
这是因为元素插入在无序集合的开头。

遍历无序集

我们必须初始化一个迭代器,该迭代器将负责遍历集合并访问每个元素。
无序集支持两个返回迭代器的内置函数。

  • begin()–将迭代器返回到集合的第一个元素。

  • end()–返回经过集合最后一个元素的迭代器。

通过这两个功能,我们将知道集合的开始和结束。

//For the usage of unordered set
#include<unordered_set>

//For input output
#include<iostream>
using namespace std;

int main(){

	//Hard-coded unordered set
	unordered_set<int> s1 = {1, 4, 8, 3, 2};

	//Initializing an iterator for unordered set
	unordered_set<int> :: iterator it;

	//Printing each element
	for(it=s1.begin(); it != s1.end(); it++)
		cout<<*it<<" ";
	cout<<endl;
}

输出:

2 3 4 8 1 

迭代器可用于使用'*'运算符获取其指向的值。

将元素添加到无序集中

元素的插入是在使用insert()函数时发生的。

//For the usage of unordered set
#include<unordered_set>

//For input output
#include<iostream>
using namespace std;

int main(){

	//Hard-coded unordered set
	unordered_set<int> s1 = {1, 4, 8, 3, 2};

	//Inserting elements in the set 
	s1.insert(5);
	s1.insert(10);
	s1.insert(4);

	//Initializing an iterator for unordered set
	unordered_set<int> :: iterator it;

	//Printing each element
	for(it=s1.begin(); it != s1.end(); it++)
		cout<<*it<<" ";

	cout<<endl;
}

输出:

10 1 8 4 3 2 5 

如果我们尝试插入无序集中已经存在的元素,则不会收到错误消息。
在无序集中插入的平均时间复杂度为O(1),在最坏的情况下可能趋于达到O(n)。

从无序集中删除元素

删除过程非常简单。
我们可以搜索最初创建的哈希表以删除特定元素。
erase()函数接收要从集合中删除的值。

//For the usage of unordered set
#include<unordered_set>

//For input output
#include<iostream>
using namespace std;

int main(){

	//Hard-coded unordered set
	unordered_set<int> s1 = {1, 4, 8, 3, 2};

	//Deleting elements from the set 
	s1.erase(8);
	s1.erase(1);
	s1.erase(5);

	//Initializing an iterator for unordered set
	unordered_set<int> :: iterator it;

	//Printing each element
	for(it=s1.begin(); it != s1.end(); it++)
		cout<<*it<<" ";

	cout<<endl;
}

输出:

2 3 4 

insert()函数类似,当我们尝试删除集合中不存在的元素时,不会引发任何错误。
添加和删除元素的复杂性是相似的。

在C++中搜索无序集中的元素

与哈希表一样,在无序集合中搜索元素非常省时。
通常情况下,只需要O(1)时间即可检查元素是否存在于集合中。

这是对有序集合的O(logN)时间复杂度的巨大改进,该集合使用平衡的BST进行内部实现。

搜索机制是通过find()函数来抽象的,该函数接受要搜索的值,并将迭代器返回到该位置。
如果不存在该值,则它将返回该集合的最后一个元素之后的迭代器。

//For the usage of unordered set
#include<unordered_set>

//For input output
#include<iostream>
using namespace std;

int main(){

	//Hard-coded unordered set
	unordered_set<int> s1 = {1, 4, 8, 3, 2};

	int value = 8;

	//Searching 'value' in the unordered set
	if(s1.find(value) != s1.end())
		cout<<value<<" is present in the set"<<endl;
	else
		cout<<value<<" is not present in the set"<<endl;

	value = 7;

	//Searching 'value' in the unordered set
	if(s1.find(value) != s1.end())
		cout<<value<<" is present in the set"<<endl;
	else
		cout<<value<<" is not present in the set"<<endl;

}

输出:

8 is present in the set
7 is not present in the set

这总结了C++ STL中无序集合的基本操作。

其他有用的设定功能

一些有用的功能可能会派上用场:

  • size()–返回无序集中元素的数量。

  • empty()–如果集合为空,则返回true,否则返回false。

  • clear()–清空整个集合。

  • swap(set1,set2)–交换作为参数传递的完整集。

  • emplace(value)–将作为参数传递的值插入到集合中。

  • count(value)–返回集合中某个值的频率,可以为1或者0。