java代码中的数组访问次数

时间:2013-06-26 07:26:15

标签: arrays algorithm

我正在通过sedgewick对quick-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()union()0,i的数组访问次数正好是2i+3(注意:在书中它打印为2i + 2,但勘误表示为2i + 3)。site 0 at at深度i和网站i的深度为0。

我试图为调用union(0,1)

解决这个问题

这涉及两个find()调用(0和1作为输入)和数组修改id[proot]= qroot

考虑find(0)

数组id []为0,1,2,3,4..

在while循环中,p = 0

test 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)的数组访问次数 - &gt; 2 * 1 + 3 = 5

我很困惑..有人能告诉我我的错误吗?

1 个答案:

答案 0 :(得分:1)

我的分析似乎同意你的观点,原始解决方案和勘误表都是错误的。我的主张是假设调用模式为2(i-1) + 3union(0, i)union(0, 1), union(0, 2), ..., union(0, i)数组访问。我们可以通过归纳来证明这一点。

特别是我们证明了一个更强有力的主张,即union(0, i)需要2(i-1 + 3数组访问 id数组看起来像1, 2, 3, ..., k-2, k, k, k+1, ..., Nk union()之后。更强烈的声明使感应清洁。

在基本情况下,正如您所观察到的,union(0, 1)有三个数组访问。此时,通过检查,我们有一个看起来像[1, 1, 2, ..., N]的数组。在归纳步骤中,我们假设声明适用于1 <= j <= k,并考虑id开头的union(0, k+1)数组的状态。此时它看起来像

[1, 2, 3, ..., k-2, k, k, k+1, ..., N]

通过归纳假设。在这一点上通过检查,我们有我们的主张。特别是,find(0)将进行2(k + 1 - 1)数组访问。 find(k+1)将需要两个。 id[0] = k+1的分配是最后一个根据需要提供给我们2((k + 1) - 1) + 2 + 1 => 2((k + 1) - 1) + 3的。请注意,该数组也将变为

[1, 2, 3, ..., k-2, k-1, k+1, k+1, k+2, ..., N]

因为我们需要感应。

你在关于这个Theta(n^2)的评论中提到的后一部分来自某些代数。特别是让f(n)成为调用union(0, 1), union(0, 2), ..., union(0, n)的数组访问次数,其中n < N是数组的大小。然后,上述声明显示f(n) - f(n-1) = 2(n - 1) + 1f(1) = 3(我们的基本情况)。那我们就有了

f(n) = f(n) - f(n-1) + 
       (f(n-1) - f(n-2)) + 
       (f(n-2) - f(n-3)) + 
       ... + 
       (f(2) - f(1)) + 
       f(1)
=>
f(n) = 2(n-1) + 3 +
       2(n-2) + 3 +
       2(n-3) + 3 +
       ... +
       2(1) + 3 + 
       2(0) + 3
=>
f(n) = Sum(2(i-1) + 3) from i = 1 to i = n

第一步是因为它“望远镜”并且通过检查是真实的。计算算术,这样的有限进展有一个很好的技巧。添加第一个和最后一个元素,然后添加第二个和倒数第二个元素,依此类推。你会注意到它们都是一样的,并且可以证明它们是一样的。我会让你搞砸了,但封闭的形式是

n^2 + 2

显示Theta(n^2)是一个“留给读者的练习”嘿。如果一切都失败了,你应该在教科书中看到相同的证据。

哦,我在评论中提到,即使它是2i+22i+3,上述证据也不会真正改变那么多。绝对花时间问这个问题,但不是几个小时......特别是如果你对你的答案有信心(通过证明我在这里做的,或在你脑海中勾勒出证据)。几乎可以肯定的是,除非1是非常重要的(有一些基本情况实际上很难看出为什么他们有一定的价值!花时间知道为什么它是0而不是1可能是有价值的),所以你必须做出自己的判断。祝你好运