您的位置:首页 > 其它

并查集的优化措施

2017-04-16 11:05 197 查看
#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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: