计算递归算法的时间复杂度

时间:2011-02-01 02:32:27

标签: algorithm big-o time-complexity

我正在尝试计算递归算法的时间复杂度,我想我差不多了。这是我一直在看的伪代码:

long pow( long x, int n ) {
    if (n == 0)
        return 1;
    if (n == 1)
    return x;
    if(isEven(n))
        return pow(x, n / 2 ) * pow(x, n / 2);
    else
        return x * pow(x * x, n / 2);
} 

isEven仅仅确定传递给它的整数是否是偶数,并且就本例而言,它是在恒定时间内运行。

因此,如果n = 0或n = 1,它运行它具有恒定时间操作,如下所示: f(n)= C0。 但是,当n> 1,它应该像这样运作: 当n为偶数时,f(n)= f(n-1)+ f(n-1)+ C1,当n为奇数时,f(n)= f(n-1)+ 1,正确吗?或者应该是:f(n)= f(n / 2)+ f(n / 2)+当n是偶数时的C1和当n是奇数时f(n)= f(n / 2)+ 1?

我一直在看很多例子。 Here是我发现非常有帮助的。我的问题源于当n是偶数时有两个递归调用 - 我不完全确定在这里做什么。如果有人能指出我正确的方向,我真的很感激。

2 个答案:

答案 0 :(得分:3)

看看Master Theorem。您可以将此视为“分而治之”算法。

最终结果是,在两个递归调用到位的情况下,最终会出现最坏情况的O(n)运行时。例如。 pow(x,4)将pow(x,2)称为两次,将pow(x,1)称为四次;一般来说,2的幂将导致n * 2-1次呼叫。

另请注意,只需调用pow(x,n / 2)一次并将结果平方化为该分支,算法就会变为O(log n)。

答案 1 :(得分:0)

让我们定义f(m),因为它给出了大小为m的问题的操作次数。 “问题”当然是取幂(pow),如x^npow(x,n)。如果我更改x,long pow( long x, int n ) {函数不需要做更多或更少的工作。因此,问题取幂的大小不依赖于x。但它确实取决于n。假设2 ^ 4的大小为4,3 ^ 120的大小为120.(如果您看到2^4=2*2*2*23^120=3*3*3*3*..*3,则有意义)问题大小因此等于n,第二个参数。如果你愿意,我们可以说问题的大小是2 * log(n),但这很愚蠢。

现在我们有f(m)是计算任何x的pow(x,m)的操作数。因为pow(x,m)正是尺寸为m的问题。 因此,如果我们有pow(x,y),那么根据定义,操作数量为f(y)例如,pow(3,3*m/2)f(3*m/2)次操作。< / p>

最后,让我们计算一下操作

long pow( long x, int n ) {
    if (n == 0)  //1
        return 1;
    if (n == 1)  //1
    return x;
    if(isEven(n)) //1
        return pow(x, n / 2 ) * //that is f(n/2), y=n / 2
                 pow(x, n / 2); //also f(n/2)
    else
        return x * pow(x * x, n / 2); //1+1+f(n/2)
} 

将它们放在一起:f(n) = 2*f(n/2) + c1(n偶数)和f(n) = f(n/2) + c2(n奇数)。如果你只对最糟糕的情况感兴趣,那么请注意奇数情况下的工作量较少。因此,f(n)在偶数情况下界定:f(n) <= 2*f(n/2)+c