【发布时间】:2018-01-27 22:41:52
【问题描述】:
快速联合算法的通用代码。
public class QuickUnionUF
{
private int[] id;
public QuickUnionUF(int N)
{
id = new int[N];
for (int i = 0; i < N; i++) id[i] = i;
}
private int root(int i)
{
while (i != id[i]) i = id[i];
return i;
}
public boolean connected(int p, int q)
{
return root(p) == root(q);
}
public void union(int p, int q)
{
int i = root(p);
int j = root(q);
id[i] = j;
}
}
这里很明显,对于像“初始化”、“联合”和“查找是否已连接”这样的联合操作,数组访问的数量将是 N 的数量级(这从代码中很清楚)。
但是,我的书声称,如果我们将 QuickUnion 修改为加权 QuickUnion,那么数组访问的数量将变为 lg(N) 的数量级。但是我看不出代码是怎么回事。
对加权 QuickUnion 所做的唯一更改是 union() 函数中的部分,如下所示:
int i = root(p);
int j = root(q);
if (i == j) return;
if (sz[i] < sz[j]) { id[i] = j; sz[j] += sz[i]; }
else { id[j] = i; sz[i] += sz[j]; }
这里我们维护额外的数组sz[i]
计算以 i 为根的树中的对象数。
但是在这里,我看不到 union 的数组访问次数是多少 lg(N)。数组访问的顺序必须是 N,因为我们必须调用 root() 方法两次。即使对于“查找是否已连接”操作,它的 lg(N) 顺序又如何?
我对他们如何获得 lg(N) 感到困惑。有人可以解释一下吗?
【问题讨论】:
标签: java arrays algorithm math