【问题标题】:Union-Find path compression efficiencyUnion-Find 路径压缩效率
【发布时间】:2024-01-18 13:44:01
【问题描述】:

我在网上找到了一些union-find tutorial 描述的路径压缩技术,它比O(log(N)) 的复杂度甚至低于find(),下面是本博客中的路径压缩实现,

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

我看到这个实现只是将路径减少了一半,并且可以使用下面的递归技巧使其更加压缩,

int recurse_root (int Arr[], int i) {
    if ( i == Arr[i] ){
        return i;
    }
    Arr[i] = recurse_root( Arr, Arr[i] )
    return A[i];
}

我想知道我是否遗漏了什么,为什么大多数在线教程都没有讨论这种技术?

【问题讨论】:

  • 好吧,当我很久以前研究这个时,我确实发现大多数地方都提到了这个。甚至在wiki page中也提到了。
  • 感谢您的澄清
  • 您还可以保留原始索引i 的副本,并在找到根后,使用迭代而不是递归进行第二次传递以将每个站点指向根。

标签: algorithm time-complexity disjoint-sets union-find


【解决方案1】:

我想知道我是否遗漏了什么,为什么大多数在线教程都没有讨论这种技术?

此类在线教程未正确使用路径压缩启发式(如您所想)或未提及它,因为很难证明其运行时间是真实的,或者他们在没有证明的情况下提及它。

我不喜欢在线教程,所以我无法确定我公开的 3 个原因中哪一个是最常见的原因。我可以告诉你的是,在《算法简介》(Cormen),第 3 版,第 569 和 570 页中,您可以找到包含图像的 路径压缩 启发式的出色解释。此外,如果您正在寻找实际运行时间的证明,请从第 573 页开始阅读(大量阅读,值得一读)。

也许它在在线教程中并不流行,但在 CS 学位中必须知道它的存在。

【讨论】: