朴素算法(适合数据量不大的)
int father[MAXN];
void make_set(int n)
{
for(int i=1;i<=n;i++)
father[i]=i;
}
int find(int x)
{
int r=x;
while(father[r]!=r)
{
r=father[r];
}
return r;
}
void unions(int x,int y)
{
int a,b;
a=find(x);
b=find(y);
if(a!=b)
father[a]=b;
}
路径压缩+按秩合并
如果查找的数据量较大,或者元素形成一条链,原本的算法会超时,采用路径压缩,在find的同时将该点连接到他的“最远”的祖先上面。采用按秩合并,rank1表示的树的秩,也就是树的高度,在合并的时候,将秩比较小的树连接到秩较大的树上面。这样找祖先会减少次数,最坏情况下也只要logn次。
int father[MAXN];
int rank1[MAXN];
void make_set(int n)
{
for(int i=1;i<=n;i++)
{
father[i]=i;
rank1[i]=0;
}
}
int find(int x){
int r=x,t;
while(father[r]!=r)
r=father[r];
while(x!=r)
{
t=father[x];
father[x]=r;
x=t;
}
return r;
}
void unions(int x,int y)
{
x=find(x);
y=find(y);
if(x==y)
return ;
if(rank1[x]>rank1[y])
father[y]=x;
else
{
if(rank1[x]==rank1[y])
rank1[y]++;
father[x]=y;
}
}