【问题标题】:Union-Find performance explanationUnion-Find 性能说明
【发布时间】:2017-09-26 11:13:59
【问题描述】:

这是参考 Robert Sedgewick 和 kevin Wayne 所著的 Algorithm (Foutth Edition) 一书

对于 Union-find 实现,find 和 union 的代码如下(第 222 页)给出:

public int find(int p)
{
  return id[p]; 
}

public void union(int p, int q)
{ 
 // Put p and q into the same component.

 int pID = find(p);
 int qID = find(q);

// Nothing to do if p and q are already in the same component.

 if (pID == qID) return;

// Rename p’s component to q’s name.

 for (int i = 0; i < id.length; i++)
      if (id[i] == pID) id[i] = qID;
 count--;
}

然后是命题:

命题 F。快速查找算法对每个使用一个数组访问 调用 find() 并在 N + 3 和 2N + 1 之间为每个数组访问 调用结合两个组件的 union()。

我想了解我们实际上是如何得出 N + 32N + 1 的。我对 N + 3 有一些想法,但对 2N + 1 不知道。请帮忙。

【问题讨论】:

    标签: algorithm union-find


    【解决方案1】:

    对于pID != qID我们有的情况:

    2 次访问:

    int pID = find(p);
    int qID = find(q);
    

    在 if 条件下循环中的 N 次访问:

    if (id[i] == pID)
    

    到目前为止 N+2,但是由于 pID != qID 至少 p 有 pID!=qID 所以我们将在 if 语句中再访问一次:id[i] = qID; 所以我们将至少访问数组 N=3 次。

    在最坏的情况下,所有 N 元素的 id 为 pID,我们将执行 id[i] = qID; N-1 次(不像以前那样只执行 N-1 次,因为 q 有 qID 所以我们不会访问 q 的数组)所以总体而言:2 + N(如果所有 N 元素访问的 for 循环中的条件)+ N-1(对于id[i] = qID; ) = 2N+1.

    例子:

    如果数组看起来像:qID qID qID pID qID(5 个元素)

    然后调用union(1,4) //1 索引是第一个元素(带有 qID),4 是第 4 个(pID)

    一开始您将有 2 个访问权限,5 个用于 if 条件,只有一个 if 条件为真 - 对于 4 个元素,它是唯一具有 pID 的元素,因此您至少拥有 2+5+1 =8= N+3

    现在以最大访问次数为例,采用数组:qID pID pID pID pID 现在你将拥有2+5 + 4(因为四个条件为真)= 11 = 2N+1(N=8)。

    【讨论】:

    • 嗨@coder,我几乎可以完全理解它。但是,您能举个例子(两种情况)并解释一下吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-16
    • 1970-01-01
    • 2012-09-05
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    相关资源
    最近更新 更多