以下功能的增长顺序是什么?
static int counter = 0;
static void Example(int n)
{
if (n == 1) return;
for (int i = 0; i < n; i++)
{
counter++;
}
Example(n / 2);
}
为了解决这个问题,我做了以下几点:
我首先摆脱内部for循环以便最终得到:
static void Example(int n)
{
if (n == 1) return;
counter++;
Example(n / 2);
}
通过分析我能够判断出该方法的增长顺序是n的对数基数2。
所以我认为最终答案将是log base 2次。我怎么能搞清楚?
答案 0 :(得分:6)
让我们看一下原始函数和修改过的函数。在原始函数中,您完成了以下工作量:
我们可以将此表示为递归关系:
让我们看看这是什么样的。我们可以通过注意
开始扩展它T(n)= n + T(n / 2)
= n +(n / 2 + T(n / 4)
= n + n / 2 + T(n / 4)
= n + n / 2 +(n / 4 + T(n / 8))
= n + n / 2 + n / 4 + T(n / 8)
我们可以在这里看到一种模式。如果我们将T(n / 2)位扩展k次,我们得到
T(n)= n + n / 2 + n / 4 + ... + n / 2 k + T(n / 2 k )
最终,当n / 2 k = 1时停止。当发生这种情况时,我们有
T(n)= n + n / 2 + n / 4 + n / 8 + ... + 1
这对此有何评价?有趣的是,该和等于2n + 1,因为和n + n / 2 + n / 4 + n / 8 + ... = 2n。因此,该第一函数是O(n)。我们也可以使用 Master Theorem 来得出这个结论,但看到这种方法也很有意思。
现在让我们来看看新功能。这一个
我们可以将此重复写为
使用与以前相同的技巧,让我们展开T(n):
T(n)= 1 + T(n / 2)
= 1 + 1 + T(n / 4)
= 1 + 1 + 1 + T(n / 8)
更一般地说,在扩展k次之后,我们得到了
T(n)= k + T(n / 2 k )
当n / 2 k = 1时停止,这发生在k = log 2 n(即lg n)时。在这种情况下,我们得到了
T(n)= lg n + T(1)= lg n + 1
在这种情况下,所以T(n)= O(lg n)。
希望这有帮助!
答案 1 :(得分:0)
现在让我们看看......这会给计数器增加1次n次。 每个呼叫n减少一半,直到达到一个。
你可以摆脱循环并使用
counter+=n;
相反,因为基本上循环将n加1到计数器,逐个。
这意味着n每次运行时都会被添加到计数器中,然后变小2,直到达到1。
所以说n = 40。 计数器: 40 - &gt; 60 - &gt; 70 - &gt; 75 - &gt; 77 - &gt; 77。 N: 40 - &gt; 20 - &gt; 10 - &gt; 5 - &gt; 2 - &gt; 1。
只是推动正确的方向(计数器+ = n;是重要部分)