(浙大-19-夏-数据结构学习笔记) 集合及其运算

集合的表示

  • 交集
  • 并集
  • 补集
  • 集合差
  • 判定一个元素是否是某一集合

并查集:集合并,查元素属于什么集合
并查集的实现:
用树表示
集合{1,3,6,9}
(浙大-19-夏-数据结构学习笔记) 集合及其运算_第1张图片
集合{2,5,8}
(浙大-19-夏-数据结构学习笔记) 集合及其运算_第2张图片
代码实现:

typedef struct Node{
	int parent;
	int Data;
}Arry;
void Function(Arry num[],int N)
{
	int i = 0,k = 0;//k代表每个集合的数量
	while( M-- )//表示有几个集合
	{
		for( k = 0; i <= N-1 && k <= NUM -1 ; i++ , k++ )//每个集合读数
			scanf("%d %d",&num[i].Data,&num[i].parent);
		num[ i - k ].parent = - k - 1;
	}
		//自动形成两棵树 
}

(图片来自中国mooc浙大数据结构-19-夏)
(浙大-19-夏-数据结构学习笔记) 集合及其运算_第3张图片


查找某个元素所在的集合

int FindX(Arry num[],int x)
{
	int i = 0;
	for(i = 0;i < maxsize && num[i].Data != X ;i++)
		if(i == maxsize) return -1;//未找到
	for(;num[i].parent >= 0;i = num[i].parent);//找到树的根,并且返回根 
		return i; 
} 

集合的并运算

  • 分别找到两个元素所在集合树的根节点
  • 如果它们不同根,则将其中一个根结点的父结点指针设置成另一个根结点的数组下标。
void Union(Arry num[],int x1,int x2)
{
	int root1,root2;
	root1 = FindX( x1 );
	root2 = FindX( x2 );
	if(root1 != root2)
		num[root1].parent = root2;
}

但是在合并的时候,某些情况可能出现合并后的树的高度很高,那么我为了解决这个问题,我们可以将每个集合的根的parent设置为该集合的元素的总的个数:(声明:图片来自中国mooc浙大数据结构-19-夏)
(浙大-19-夏-数据结构学习笔记) 集合及其运算_第4张图片

void Union(Arry num[],int x1,int x2)
{
	int root1,root2;
	root1 = FindX( x1 );
	root2 = FindX( x2 );
	if(root1 != root2)
	{
		if( 0 - num[root1].parent > 0 - num[root2].parent )//因为parent的存储值是小于零的
			num[root2].parent = root1;
		else
			num[root1].parent = root2;
	}
}

例题连接05-树8 File Transfer(文件传输)–路径压缩

你可能感兴趣的:(数据结构)