三、set集合容器-遍历删除查找与自定义

简介:要学习set集合容器,首先要了解红黑树(Red-black Tree)。红黑树是一种自平衡二叉查找树,是计算机科学中用到的一种数据结构,典型的用途是实现关联数组。Set集合容器实现了红黑树的平衡二叉检索树的数据结构,在插入元素时,它会自动调整二叉树的排列,把该元素放到适当的位置,以确保每个子树根节点的键值大于左子树所有节点的键值,而小于右子树所有节点的键值;另外,还得确保根节点左子树的高度与右子树的高度相等,这样,二叉树的高度最小,从而检索速度最快。值得注意的是,它不会重复插入相同键值的元素,会采用忽略处理。如图,即是一个典型的红黑树。

平衡二叉检索树的检索使用中序遍历算法检索效率高于vector、deque和list等容器。采用中序遍历算法可以将键值由小到大遍历出来,即可以理解为:平衡二叉检索树在插入元素时会自动将元素按键值由大到小的顺序排列。

set集合容器的键值不能直接修改。因为如果将容器中的一个键值修改了,set容器会根据新的键值旋转子树,以保持新的平衡。

set集合容器的用法:

1.使用set集合容器需要头文件“#include<set>”

2.创建set集合对象   set<int>  s;//需要指定元素的类型

3.insert();将元素插入的到集合中

4.reverse_iterator;反向遍历集合

  rbegin();反向遍历的开始位置

  rend();反向遍历的结束位置

5.erase();删除元素

6.find();查找元素

7.size();集合中元素的数目

8.empty();判断集合是否为空

9.clear();清除所有元素

1、元素的插入与中序遍历

   用insert()方法把元素插入集合中去。插入的默认规则是按由小到大插入。如果自己指定了比较规则函数,可以按照自定义比较函数插入。

(1)普通方法:

#include<iostream>
#include<set>
using namespace std;
int main()
{
	set<int> s;
	s.insert(8);
	s.insert(9);
	s.insert(7);
	s.insert(8);//第二次插入8,重复元素,不会插入,自动忽略
	set<int>::iterator it;
	for(it=s.begin();it!=s.end();it++)
	{
		cout<<*it<<" ";
	}
	cout<<endl;
	return 0;
}

 

结果如下:

(2)自定义比较函数

1)非结构体类型

#include<iostream>
#include<set>
using namespace std;

struct myComp//自己定义比较函数,要求由大到小排序
{
    bool operator() (const int &a,const int &b)
	{
        return a>b; //从大到小排序
	}
};

int main()
{
	set<int,myComp> s;
	s.insert(8);
	s.insert(9);
	s.insert(7);
	s.insert(8);//第二次插入8,重复元素,不会插入,自动忽略
	set<int,myComp>::iterator it;
	for(it=s.begin();it!=s.end();it++)
	{
		cout<<*it<<" ";
	}
	cout<<endl;
	return 0;
}

 

结果如下:

2)结构体类型

#include <iostream>
#include <set>
#include <iterator>
#include <string>
using namespace std;
struct My	//重载操作符<,自定义排序规则
{
	string name;
	float score;
	bool operator< (const My &a)const
	{
		return a.score<score;	//按score由大到小排列
	}
};
 
int main()
{
	set<My> s;
	My my;

	my.name = "Tom";
	my.score = 18.5;
	s.insert(my);

	my.name = "lili";
	my.score = 19.0;
	s.insert(my);

	my.name = "My";
	my.score = 17.0;
	s.insert(my);

	my.name = "ben";
	my.score = 18.0;
	s.insert(my);

	
	set<My>::iterator it;

	for(it = s.begin(); it != s.end(); it++)
	{
		cout<<(*it).name<<" : "<<(*it).score<<endl;
	}
		return 0;
}

 

结果如下:

2、元素的反向遍历

使用反向迭代器rever_iterator可以反向遍历集合,输出的结果正好与集合元素相反。

  rbegin();反向遍历的开始位置

  rend; 反向遍历的结束位置

#include<iostream>
#include<set>
using namespace std;
int main()
{
	set<int> s;
	s.insert(2);
	s.insert(1);
	s.insert(3);
	s.insert(2);//第二次插入2,重复元素,不会插入
	set<int>::reverse_iterator i;//定义反向迭代器
	for(i=s.rbegin();i!=s.rend();i++)
	{
		cout<<*i<<" ";
	}
	cout<<endl;
	return 0;
}

 

结果如下:

3、元素的删除和查找

erase() 删除元素;删除的对象可以是迭代器位置上的元素、等于某键值的元素、一个区间上的元素和清空集合。

clear()清空集合

find()对集合进行搜索,如果找到该键值,则返回该键值的迭代器位置,否则,返回集合最后一个元素后面的一个位置(即end())。

size()返回集合大小

#include<iostream>
#include<set>
using namespace std;
int main()
{
	set<int> s;
	int i;
	for(i=0;i<10;i++)//插入0~9
	{
		s.insert(i);
	}
    set<int>::iterator it;
	for(it=s.begin();it!=s.end();it++)//输出插入的元素
	{
		cout<<*it<<" ";
	}
	cout<<endl;
	s.erase(3);//删除键值为3的元素
	s.erase(6);//删除键值为6的元素
	for(it=s.begin();it!=s.end();it++)//输出删除后剩下的元素
	{
		cout<<*it<<" ";
	}
	cout<<endl;

	it=s.find(9);//查找键值为9的元素
	if(it!=s.end())//找到
	{
		cout<<*it<<endl;
	}
	else//没找到
		cout<<"not find it"<<endl;

	it=s.find(3);//查找键值为3的元素
	if(it!=s.end())//找到
	{
		cout<<*it<<endl;
	}
	else//没找到
		cout<<"not find it"<<endl;

	s.clear();//清空集合
	cout<<s.size()<<endl;//输出集合的大小

	return 0;
}

结果如下:

 

猜你喜欢

转载自blog.csdn.net/ysz171360154/article/details/84142947