当前位置: 首页 > 知识库问答 >
问题:

带路径压缩算法的加权快速联合:时间复杂度分析

杭永安
2023-03-14

我正在学习联合/查找结构的“加权快速联合与路径压缩”算法。普林斯顿edu网站详细解释了该算法。这是Java的实现:

public class WQUPC {
  private int[] id;
  private int[] sz;
  public WQUPC(int N) {
    id = new int[N];
    sz = new int[N];
    for (int i = 0; i < N; i++) {
      id[i] = i;
      sz[i] = 1;
    }
  }

  int root(int i) {
    while (i != id[i]) {
      id[i] = id[id[i]];
      i = id[i];
    }
    return i;
  }

  boolean connected(int p, int q) { return root(p) == root(q); }

  void union(int p, int q) {
    int i = root(p);
    int j = root(q);
    if (sz[i] < sz[j]) {
      id[i] = j;
      sz[j] += sz[i];
    } else {
      id[j] = i;
      sz[i] += sz[j];
    }
  }
}

但就像网站提到它的性能一样:

定理:从空数据结构开始,任何 M 并集序列和对 N 个对象的查找操作都需要 O(N M lg* N) 时间。

证明非常困难。

但是算法仍然很简单!

但我仍然很好奇迭代对数lg*n是如何产生的。它是如何推导出来的?有人可以证明它或只是以直观的方式解释它吗?

共有2个答案

束阳旭
2023-03-14

我记得,证明是将路径压缩的成本分摊到一组搜索上。浅搜索很便宜,而且不会产生太多路径压缩的成本;深度搜索的搜索和路径压缩成本很高,但是路径压缩使后续搜索平均便宜得多。

鲜于德泽
2023-03-14

首先,您的问题有一个小错误:仅路径压缩的复杂性仅为O(m log(n))(没有迭代日志)。例如,请参阅算法简介中的练习21-4.4。事实上,你阻止了

    if (sz[i] < sz[j]) {
      id[i] = j;
      sz[j] += sz[i];
    } else {
      id[j] = i;
      sz[i] += sz[j];
    }

按等级合并。

不过,通过使用union by rank和path compression,可以很容易地证明您使用的表达式(比逆阿克曼表达式容易得多)。证据基于三点:

>

  • 在每个叶根路径上,每个节点的排名都在增加。这实际上依赖于按等级合并,顺便说一句,并且,有了它,它很容易显示。

    如果树的根具有秩r,则树至少有2个r节点。这可以通过归纳来证明。

    基于2.,可以显示

    接下来的证据是对最糟糕的等级组织方式的巧妙安排,这仍然表明没有太多的人是坏的。欲了解更多细节,请参见维基百科关于此的条目。

  •  类似资料:
    • 根据Princeton booksite,带有路径压缩的加权快速联合将10^9联合对10^9对象的操作时间从一年减少到大约6秒。这个数字是怎么得出的?当我在10^8操作中运行下面的代码时,我的运行时间是61s。

    • 我有一个项目,我必须实现一个带有路径压缩算法的加权快速并集。在看到其他一些源代码后,我最终得到了这个: 分配给我的任务是正确完成以下方法: int find(int v) void unite(int v,int u) setCount(int v) 嗯,算法似乎很慢,我找不到合适的解决方案。

    • 我正在为联合/查找结构实现快速联合算法。在“Java中的算法”一书网站上给出的实现中,普林斯顿实现在实现路径压缩(在方法中)时无法保持树的大小不变。这不应该对算法产生不利影响吗?还是我错过了什么?另外,如果我是对的,我们将如何修改大小数组?

    • 有一种“带路径压缩的加权快速联合”算法。 代码: 问题: > 路径压缩是如何工作的意味着我们只到达节点的第二个祖先,而不是根。 包含从 到 整数。如何帮助我们知道集合中元素的数量? 有人能帮我澄清一下吗?

    • 针对并集寻找不相交集的问题,提出了带路径压缩的加权快速并集算法 带路径压缩算法的加权快速并集 路径压缩会影响iz[]数组(包含以I为根的树的长度的数组)吗?

    • 处理以下问题(https://leetcode.com/problems/friend-circles/): 一个班有N个学生。他们有些是朋友,有些不是。他们的友谊本质上是可传递的。比如A是B的直接好友,B是C的直接好友,那么A就是C的间接好友,而我们定义的朋友圈就是一群直接或者间接好友的同学。 给定一个N*N矩阵M,表示班级学生之间的朋友关系。如果M[i][j]=1,则第i和第j个学生是彼此的直