Big-O复杂度递归与迭代

时间:2016-01-30 13:43:39

标签: recursion iteration big-o computer-science

关于Determining complexity for recursive functions (Big O notation)的问题5是:

int recursiveFun(int n)
{
    for(i=0; i<n; i+=2)
        // Do something.

    if (n <= 0)
        return 1;
    else
        return 1 + recursiveFun(n-5);
}

要突出显示我的问题,我会将递归参数从n-5更改为n-2

int recursiveFun(int n)
{
    for(i=0; i<n; i+=2)
        // Do something.

    if (n <= 0)
        return 1;
    else
        return 1 + recursiveFun(n-2);
}

我理解循环在n/2中运行,因为标准循环在n中运行,我们迭代的次数是一半。

但递归调用也不一样吗?对于每个递归调用,n递减2.如果n为10,则调用堆栈为:

recursiveFun(8)
recursiveFun(6)
recursiveFun(4)
recursiveFun(2)
recursiveFun(0)

...这是5个电话(即10/2n/2)。然而,Michael_19提供的答案表明它在n-5中运行,或者在我的示例中运行n-2。显然,n/2n-2不同。我在哪里出错了,为什么递归与分析Big-O时的迭代不同?

1 个答案:

答案 0 :(得分:4)

分析递归算法的big-O的常用方法是找到一个递归公式,即&#34;计数&#34;算法完成的操作次数。它通常表示为T(n)

在您的示例中:此代码的时间复杂度可使用以下公式进行描述:

T(n) = C*n/2                                   +    T(n-2)
       ^                                              ^
    assuming "do something is constant        Recursive call

由于它很明显会出现在O(n^2)中,让我们使用归纳法显示Omega(n^2)

归纳假设:

T(k) >= C/8 *k^2  for 0 <= k < n

确实:

T(n) = C*n/2 + T(n-2) >= (i.h.) C*n/2 + C*(n-2)^2 / 8
     = C* n/2 + C/8(n^2 - 4n + 2) =
     = C/8 (4n + n^2 - 4n + 2) =
     = C/8 *(n^2 + 2)

确实:

T(n) >= C/8 * (n^2 + 2) > C/8 * n^2

因此,T(n)位于big-Omega(n^2)

显示大O也是类似的:

假设:T(k) <= C*k^2适用于所有2 <= k < n

T(n) = C*n/2 + T(n-2) <= (i.h.) C*n/2 + C*(n^2 - 4n + 4) 
     = C* (2n + n^2 - 4n + 4) = C (n^2 -2n + 4)

适用于所有n >= 2-2n + 4 <= 0,因此适用于任何n>=2

T(n) <= C (n^2 - 2n + 4) <= C^n^2

假设是正确的 - 根据big-O的定义,T(n)在O(n ^ 2)中。

由于我们已经证明T(n)在O(n ^ 2)和Omega(n ^ 2)中,它也在Theta(n^2)

分析递归与分析迭代不同,因为:

  1. n(以及其他局部变量)每次都会更改,并且可能很难捕捉到这种行为。
  2. 当有多个递归调用时,事情变得更加复杂。