分析递归函数(甚至对其进行评估)是一项非常棘手的任务。我认为,Don Knuth的
Concrete Mathematics中可以找到很好的介绍。
现在让我们分析这些例子:
我们定义一个函数,它给出了一个函数所需的时间。假设
t(n)
表示
pow(x,n)
所需的时间,即
n
的函数。
然后我们可以得出结论,
t(0)=c
,因为如果我们调用
pow(x,0)
,我们必须检查是否(
n==0
),然后返回1,这可以在恒定时间内完成(因此是常数
c
)。
现在我们考虑另一种情况:
n>0
。在这里,我们得到
t(n) = d + t(n-1)
。这是因为我们再次需要检查
n==1
,计算
pow(x, n-1
,因此(
t(n-1)
),并将结果乘以
x
。检查和乘法可以在恒定时间内完成(常数
d
),
pow
的递归计算需要
t(n-1)
。
现在我们可以“展开”术语
t(n)
:
t(n) =
d + t(n-1) =
d + (d + t(n-2)) =
d + d + t(n-2) =
d + d + d + t(n-3) =
... =
d + d + d + ... + t(1) =
d + d + d + ... + c
那么,我们需要多长时间才能到达t(1)
?因为我们从t(n)
开始,并且每一步减去1,所以需要n-1
步才能到达t(n-(n-1))= t(1)
。另一方面,这意味着我们获得了n-1
次常数d
,并且t(1)
的值为c
。
因此,我们得出:
t(n) =
...
d + d + d + ... + c =
(n-1) * d + c
所以我们得到 t(n)=(n-1) * d + c
,它是 O(n) 的元素。
pow2
可以使用 主定理 进行计算。因为我们可以假设算法的时间函数单调递增。现在我们有了计算 pow2(x,n)
所需的时间 t(n)
:
t(0) = c (since constant time needed for computation of pow(x,0))
对于 n>0
,我们得到
/ t((n-1)/2) + d if n is odd (d is constant cost)
t(n) = <
\ t(n/2) + d if n is even (d is constant cost)
上述内容可以“简化”为:
t(n) = floor(t(n/2)) + d <= t(n/2) + d (since t is monotonically increasing)
所以我们得到了 t(n) <= t(n/2) + d
,可以使用主方法求解为 t(n) = O(log n)
(请参见维基百科链接中的“流行算法应用”部分,例如“二分查找”的示例)。