int Find(int Set[ ], int x)
/*找某个元素所在的集合*/
int FindSet1(int Set[], int x)
{
for ( ; Set[x] >= 0; x = Set[x]) ;
return x;
}
/*FindSet的路径压缩
当Find一颗很高的树时,多次Find会效率很低
解决办法就是每次Find都将高度降低
利用递归,每次查找到根,从根开始向后改变父亲
最终使该条路径上的元素都2直接指向Root
*/
int FindSet(int Set[], int x) //返回值为集合的根(记忆化搜索)
{
if(Set[x] < 0) //找到根后,返回根
return x;
else
return Set[x] = FindSet(Set, Set[x]); //如果不是根,向上继续找根
}
void Union(int Set[ ])
/*集合的并运算*/
void UnionSet1(int Set[], int Root1, int Root2)
{
/*Root1, Root2分别是两个不同集合的根*/
Set[Root1] = Root2;
} //直接简单并运算可能导致生成集合的树越来越高,为解决该问题,采用按秩合并
/*集合按秩合并
改进方法:
已知集合的根的parent都是-1,
现在将其改为-n,n表示的就是该集合的元素个数
两个集合比较大小,然后将小集合并到大集合
*/
void UnionSet(int Set[], int Root1, int Root2)
{
if(Set[Root1] > Set[Root2]) //表示集合2更大
{
Set[Root2] += Set[Root1]; //更新集合大小
Set[Root1] = Root2; //并运算
}
else
{
Set[Root1] += Set[Root2];
Set[Root2] = Root1;
}
}