我正在通过sedgewickquick-union algorithm
书中的分析。作者给出了这段代码和注释Algorithms 4th ed
...
for(int i =0; i< N; i++){
id[i] = i;
}
...
private int find(int p){
while(p != id[p]){
p = id[p];
}
return p;
}
public void union(int p, int q) {
int proot = find(p);
int qroot = find(q);
if (proot == qroot){
return;
}
id[proot] = qroot;
this.count--;
}
考虑最坏的情况,其中 p,q 对 (0,1),(0,2),(0,3),(0,4) 等被赋予union()
.autor 评论说对的数组访问union()
次数0,i
是完全正确2i+3
(注意:在书中它打印为 2i+2,但勘误表说 2i+3)。站点 0 位于深度 i,站点 i 位于深度 0。
我试图为 call union(0,1) 解决这个问题
这涉及两个find()
调用(以 0 和 1 作为输入)和一个数组修改id[proot]= qroot
考虑 find(0)
数组 id[] 是0,1,2,3,4..
在while循环中,p =0
测试 0 != id[0] 失败,因为 id[0]=0 。所以,在 find(0) 中只有 1 个数组访问
在 find(1) 中,test 1 != id[1] 失败,因此 find(1) 只访问 1 个数组。
然后 id[proot] = qroot 仅导致 1 次数组访问。
总共有 3 个数组访问。
但是当使用等式 2i+3 时(对于 (0,i) 对)
对 (0,1) 的数组访问次数 -> 2*1+3 = 5
我很困惑..有人可以告诉我我错在哪里了吗?