这是我最近发现的来自算法和数据结构的旧考试之一的问题。我很难理解解决方案。
我需要查找函数的big-O
,big-ϴ
和big-Ω
边界:
void recursion(int n) {
int i;
if (n == 0) {
return;
}
for (i = 0; i < n; i++) {
recursion(i);
}
}
所有三个解决方案都是2^n
,我无法理解为什么。我已经尝试过写下来了,我甚至无法接近解决方案。如果有人能解释2^n
来自何处,我将不胜感激。
答案 0 :(得分:2)
由于这有点像家庭作业问题,这个答案在设计上是不完整的。
这类问题背后的通常技巧是创建一个递归方程。也就是说,recursion(k+1)
的时间复杂度在某种程度上与recursion(k)
的复杂性有关。只写下复发本身并不足以证明复杂性,你必须证明为什么复发是正确的。但是,对于2 n ,这表明recursion(k+1)
的时间是recursion(k)
的两倍。
设p(k)表示recursion(k)
的时间复杂度。由于recursion(0)
立即返回,因此让T(0)= 1.对于k&gt; 0,给定recursion
的{{0}}的迭代实施,因此为
{{ 0}}你可以归纳证明T(k)= 2 k 。
答案 1 :(得分:2)
我们将总运行时间表示为f(n)
。由于函数中的循环,f(n)
实际上是f(i)
的{{1}}之和,介于0和n-1之间。这是i
项的总和。让我们尝试简化表达式。在这种情况下的标准技巧是找到一个互补的等式。让我们看看n
的价值是什么。与前一种情况类似,它是f(n-1)
与f(i)
在0和n-2之间的总和。所以现在我们有两个方程式:
i
让我们从第一个中减去第二个:
f(n)=f(1)+...+f(n-1)
f(n-1)=f(1)+...+f(n-2)
现在这是一个homogeneous linear recurrence relation with constant coefficients。 解决方案是即时的(有关详细信息,请参阅链接):
<强> F(N)= F(1)* 2 名词 = 2 名词 强>
答案 2 :(得分:2)
让我们看一个更简单的递归,它已知为O(2 ^ n)
void fib(int n) {
if (n < 3) {
return 1;
} else {
return fib(n - 1) + fib(n - 2);
}
}
在这里你可以看到,对于n&gt;的非平凡情况; 2,这将导致2 ^(n-2)次调用。例如,如果n = 5:
n = 5
n = 4
n = 3
n = 2
n = 1
n = 2
n = 3
n = 2
n = 1
有8(2 ^ 3)个递归调用,因为每个调用n&gt; 2产生两个递归调用,因此fib(n + 1)的递归调用是fib(n)的两倍。
所以对你的例子来说:
n = 3
n = 2
n = 1
n = 0
n = 0
n = 1
n = 0
n = 0
所以当n = 3时,我们得到7次递归调用
对于n = 4
n = 4
n = 3
n = 2
n = 1
n = 0
n = 0
n = 1
n = 0
n = 0
n = 2
n = 1
n = 0
n = 0
n = 1
n = 0
n = 0
在这里,我们有15个电话。查看上面的执行树,你可以看到recusrsion(4)基本上是递归(3)+递归(3)+ 1
n = 4
n = 3 // + 1
n = 2 //
n = 1 //
n = 0 // recursion(3)
n = 0 //
n = 1 //
n = 0 //
n = 0 //
n = 2 //
n = 1 //
n = 0 // recursion(3)
n = 0 //
n = 1 //
n = 0 //
n = 0 //
所以一般来说,递归(n + 1)将有一个递归调用而不是2 *递归(n)....这基本上是每个+1到n加倍....这是O(2 ^ n)的
答案 3 :(得分:1)
r(n) = r(n-1)+r(n-2)+...+r(0) // n calls.
r(n-1) = r(n-2)+r(n-3)+...+r(0) // n-1 calls.
r(n-2) = r(n-3)+r(n-4)+...+r(0) // n-2 calls.
.
.
.
r(1) = r(0) // 1 call.
r(0) = return; // 0 call.
所以,
r(n) = r(n-1)+r(n-2)+...+r(0) // n calls.
= 2 * (r(n-2)+...+r(0)) // 2 * (n - 1) calls.
= 2 * ( 2 * (r(n-3)+...+r(0)) ) // 2 * 2 * (n - 2) calls.
.
.
.
这是=&gt;
2^(n-1) * (n - (n-1))
那就是
2^n calls...