联盟按大小无限循环

时间:2015-04-01 16:07:16

标签: java loops data-structures union-find

我正在从头开始实现一个Union-Find数据结构,遇到一个问题,如果尝试重复一个union调用,无限循环会导致我的find方法。

我正在使用路径压缩来实现 Union By Size 。 我创建了一个只有10个元素(0到N-1)的测试实现

示例:

U 3 1  //Union 1 -> 3
U 0 2  //Union 2 -> 0
U 0 2  //Union 2 -> 0 , infinite loop results
U 1 4  //Union 4 -> 1 , results in infinite loop

当我执行第二个U 0 2时,循环被捕获,因为索引2处的值为零,并且根也为零,因此循环地重复循环。当我尝试U 1 4时,会遵循相同的逻辑。我在find中的第二个循环有不正确的逻辑。

我的问题是:我如何处理这些案件,以免陷入这种无限循环?

这是我的查找方法:

/*
 * Search for element 'num' and returns the key in the root of tree
 * containing 'num'. Implements path compression on each find. 
 */
public int find (int num) {
    totalPathLength++;
    int k = num;
    int root = 0;
    // Find the root
    while (sets[k] >= 0) {
        k = sets[k];
        totalPathLength++;
    }
    root = k;
    k = num;

    // Point all nodes along path to root
    /* INFINITE LOOP OCCURS HERE */
    while (sets[k] >= 0) {
        sets[k] = root;
    }
    return root;
}

我如何调用与工会相关的发现:(位于主要部分)

   int x = Integer.parseInt(tokens[1]);
   int y = Integer.parseInt(tokens[2]);
   // Call to find upon the 2nd: U 0 2, results in inf. loop
   if (uf.find(x) == x && uf.find(y) == y) {
        uf.union(x, y);
   }

1 个答案:

答案 0 :(得分:1)

您不会遍历第二个循环中的路径。这意味着您num是根或您的方法进入无限循环。像这样改变你的循环:

while (sets[k] >= 0) {
    // save old parent to variable
    int next = sets[k];

    sets[k] = root;
    k = next;
}