联合查找不相交+路径压缩算法

时间:2014-06-26 22:07:51

标签: algorithm union-find

我正在考试这个星期天,我只想确认我所做的事情是否正确(你知道考试让我持怀疑态度)

这就是算法的工作原理:

int Find(int x)
{ // Return the set containing x and compress the path from x to root
  // First, find the root
int z = x; while (P[z] > 0) { z = P[z]; } int root = z;
// Start at x again and reset the parent // of every node on the path from x to root z = x;
while (P[z] > 0)
{ int t = P[z];
     P[z] = root; // Reset Parent of z to root
z = t; }
return root; }

这就是问题:

  

回想一下为不相交的Union-Find问题开发的算法   从一组n个元素中设置。 Find使用路径压缩和Union   使用排名。此外,同一级别的两棵树联盟选择了   root与第二个参数关联为新根。从集合S开始   = {1,2,...,10}和10个不相交的子集,每个子​​集包含一个元素。一个。执行后绘制最后一组树:
              联盟(1,2),联盟(3,4),联盟(5,6),联盟(1,5),联盟(1,3)。

这是我对这个问题的解决方案:

enter image description here

我希望对此算法有任何提示或建议。

谢谢!

1 个答案:

答案 0 :(得分:0)

Union-Find Set的查找操作的关键点是 路径压缩

如果我们知道集合A的根是r1,集合B的根是r2,那么当连接集A并将B集合在一起时。最简单的方法是将集合B的根设置为集合A的根,这意味着father[r2] = r1;

但它不是那么“聪明”,当r2的儿子,我们说x,想知道它的根,x问其父亲r2,然后父亲r2询问自己的父亲r1,blabla,直到根r1。下次当再次询问x的root时,x会询问其父亲r1我们的根目录是什么?”,r1没有必要再次重复上一个循环。由于r1已知其根为r2r1可以直接将其返回x

简而言之, x的root也是x的父根 。所以我们得到了如何实现 路径压缩 (我认为递归更直接):

int Find(int x)
{
    // initial each element's root as itself, which means father[x] = x;
    // if an element finds its father is itself, means root is found
    if(x == father[x])
        return father[x];
    int temp = father[x];
    // root of x's father is same with root of x's father's root
    father[x] = Find(temp);
    return father[x];
}

性能非常高,关于路径压缩查找操作的时间复杂度,请参阅:http://www.gabrielnivasch.org/fun/inverse-ackermann