并查集的优化措施

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define MaxN 10000
int a[MaxN];
int find(int X)
{
	if(a[X]!=X)
		return find(a[X]);
	else
		return X;					//找根节点 
}
void Union(int x,int y)
{
	int x1,x2;
	x1=find(x);
	x2=find(y);						//找两个集合所在元素的根节点 
	if(x1!=x2)
		a[x1]=x2;					//合并根节点,即合并集合 
 } 
int main()
{
	int N;
	scanf("%d",&N);
	int i;
	for(i=1;i<=N;i++)
		a[i]=i;					// 建立N个集合,每个数组中的元素代表这个数组下标的父节点,如果下标与元素相同
								//说明这个节点为根节点 
    return 0;
}

这是基础的并查集,效率略低,如果树的高度过高就会很慢

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define MAXN 1000
typedef int ElementType;
typedef int SetName;
typedef ElementType SetType[MAXN];
void Union(SetType S,SetName Root1,SetName Root2)		//这里假设Root1 , Root2均为根不同集合的根节点,根节点里的数字代表集合的个数 
{
	if(S[Root1]<S[Root2])
	{
		S[Root2]+=S[Root1];
		S[Root1]=Root2;
	} 
	else
	{
		S[Root1]+=S[Root2];
		S[Root2]=Root1;
	}
} //优化后的合并方法,实现了小树并到大树里,可以有效减少Find的搜索次数 
SetName Find(SetType S,ElementType X)
{
	if(S[X]<0)
		return X;
	else
		return S[X]=Find(S,S[X]);				//路径压缩 
} 
int main()
{
	int N;
	scanf("%d",&N);
	SetType S;
	int i ; 
	for(i=1;i<=N;i++)
		S[i]=-1;						//初始化N个集合,并将根节点赋值为负数,符号后面的数字代表了集合的元素个数
											// 例如 S[1]=-2代表了下标为1的位置的节点是一个根节点,且此集合中有两个元素 
    return 0;
}


这是优化后的,

思路出自中国大学MOOC陈越何欣铭的数据结构课堂讲课

http://www.icourse163.org/learn/ZJU-93001#/learn/content?type=detail&id=1002635019&cid=1002891124

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值