让我们看一下代码,看看递归应该是什么。
首先,让我们看一下循环:
for i=1 to n
{
for j=i to 2i
{
for k=j-i to j-i+100
write (i, j, k);
}
}
这做了多少工作?好吧,让我们从简化它开始。让我们定义一个从to向上计数的新变量,而不是j
从to计数。这意味着= ,所以我们得到这个:i
2i
j'
0
i
j'
j - i
for i=1 to n
{
for j' = 0 to i
{
for k=j' to j'+100
write (i, j' + i, k);
}
}
啊,这样好多了!现在,我们也重写k
为k'
,k'
范围从 1 到 100:
for i=1 to n
{
for j' = 0 to i
{
for k'= 1 to 100
write (i, j' + i, k' + j);
}
}
由此,更容易看出这个循环的时间复杂度为 Θ(n 2 ),因为最里面的循环做了 O(1) 的工作,而中间的循环将运行 1 + 2 + 3 + 4 + ... + n = Θ(n 2 ) 次。请注意,它不完全是 100n 2,因为总和不完全是 n 2,但它很接近。
现在,让我们看一下递归部分:
for i=1 to 7
Alg(n-2);
对于初学者来说,这简直是愚蠢的!你没有理由想要做这样的事情。但是,也就是说,我们可以说这是对大小为 n - 2 的输入的算法的 7 次调用。
因此,我们得到这个递归关系:
T(n) = 7T(n - 2) + Θ(n 2 ) [如果 n ≥ 3]
T(n) = Θ(1) [否则]
现在我们有了递归,我们可以开始计算时间复杂度。这最终有点棘手。如果你想想我们最终会做多少工作,我们会得到的
- 有 1 个大小为 n 的调用。
- 有 7 个大小为 n - 2 的调用。
- 有 49 个大小为 n - 4 的调用。
- 有 343 个大小为 n - 6 的调用。
- ...
- 有 7 k个大小为 n - 2k 的调用
由此,我们立即得到 Ω(7 n/2 )的下限,因为这是将要进行的调用次数。每次调用都会 O(n 2 ) 工作,因此我们可以获得 O(n 2 7 n/2 ) 的上限。真正的价值就在那里,虽然老实说我不知道如何弄清楚它是什么。对于那个很抱歉!
希望这可以帮助!