指数复杂性

时间:2017-03-14 13:36:24

标签: c algorithm time-complexity analysis

基于此代码:

int poow(int x,int y)
{
    if(y==0)
        return 1;

    if(y%2!= 0)
        return poow(x,y-1)*x;

    return poow(x,y/2)*poow(x,y/2); //this line 

}

我试图看到复杂性:我们假设我们有n = 2 ^ k

我们有T(0)= 1

T(N)= 2 * T(N / 2)+ C

T(n)= 2 ^ i * T(n / 2 ^ i)+ i * c

对于i = k,我们得到T(n)= 2 ^ k * T(n / 2 ^ k)+ k * c

T(n)= 2 ^ k * T(1)+ k * c

T(n)= 2 ^ k * c2 + k * c

我被困在这里?如何继续计算复杂性以及更改此行时的区别:

return poow(x,y/2)*poow(x,y/2); //this line 

int p=poow(x,y/2);
return p*p;

就复杂性而言!

2 个答案:

答案 0 :(得分:1)

从适当的重复开始。复杂性完全基于y,因此我们可以将重现写为

T(0) = 1

T(y) = y is even:     2 * T(y / 2)
       y is odd:      T(y - 1) + 1

最糟糕的情况是每个除以2会给我们留下一个奇数,这会导致复杂性

T(2^n-1) = 1 + 2 * (1 + 2 * (1 + 2 * ( ... * T(1)))) =
         = 2 ^ 0 + 2 ^ 1 + 2 ^ 2 + 2 ^ 3 + ... + 2 ^ (n - 1) + 2 ^ (n - 1) = 
         = 2 ^ n - 1 + 2 ^(n - 1) = 3 * 2 ^ (n - 1) - 1

T(y) = O(y)

最好的情况是2的力量:

T(2^n) = 2 * 2 * ... * 2 * T(1) = 2 ^ n * (1 + 1) = 2 ^ (n + 1) = 2 * 2 ^ n

T(y) = O(y)

现在我们如何优化整个功能呢?

T'(0) = 1

T'(y) = y is even:   T(y / 2) + 1
        y is odd:    T(y - 1) + 1

最坏情况:

T'(2^n - 1) = T(2^n - 2) + 1 = T(2^(n - 1) - 1) + 1 + 1 = ... =
            = T(1) + 1 + 1 + 1 + ... =
            = 2 + 1 + 1 + 1 + ... =
            = 1 + ln(2^n) / ln(2) * 2 = 
            = 1 + 2 * n

T'(y) = O(log y)

最佳案例:

T'(2 ^ n) = T(1) + 1 + 1 + ... =
          = 2 + 1 + 1 + ... =
          = 2 + ln(2^n) / ln(2)
          = n + 2

T'(y) = O(log y)

因此,优化版本肯定更快(线性与对数复杂度)。

答案 1 :(得分:0)

有时代码分析侧重于理论,而不是实际。

代码有一个错误。

if(y%2!= 0)
    return poow(x,y-1)*x;
// should be
if(y%2!= 0)
    return poow(x,y-y%2)*x;

// better alternative, use 
unsigned poow(unsigned x, unsigned y) 

如果没有修复,调用poow(1,-1)会导致无限递归并且可能会发生堆栈溢出。所以在最后一行中的O(∞)是return poow(x,y/2)*poow(x,y/2);int p=poow(x,y/2); return p*p;