不相交集合数据结构保持一组不相交的动态集合s={s1,s2,...},每个集合通过一个代表来识别,代表是集合中的某个元素。
不相交集合的应用较为经典的是判断会不会构成连通图,用于最小生成树的Kruskal算法。
基本操作有:
make_set(x):建立一个新的集合,其唯一成员也就是代表为X。代表X都不同,起初各个集合肯定是不相交的。
union(x,y):将包含x,y元素的集合合并为一个新的集合,此时要选出一个新的代表来代表这个集合,并且将原先的包含x,y元素的集合删除掉,将新集合加入到S中
find_set(x):返回包含x元素的集合的那个代表。
综上所述,如何来选择新集合的代表和find_set(x)将是我们要考虑到周密的问题。
接下来我们介绍按秩合并和路径压缩启发式的方法来解决这个问题
看代码分析吧:
#define N 1000
int p[N],rank[N];
void make_set(int x)
{
p[x]=x;
rank[x]=0;
}
void union(int x,int y)
{
if(rank[x]>rank[y])
p[y]=x;
else if(rank[x]<rank[y])
p[x]=y;
else if(rank[x]==rank[y]){
p[x]=y;
rank[y]++;
}
}
int find_set(int x)
{
if(x!=p[x])
p[x]=find_set(p[x]);
return p[x];
}
建议读者好好几个例子来分析下咯。。。