1.3.1 时间复杂度

算法效率的度量

事后统计:不可取

事前预估:预估算法开销问题规模之间的关系。

时间复杂度

算法时间开销T(n)问题规模 n之间的关系。

对于顺序和分支语句,n 和 T(n) 为常数。

对于循环,n 与循环次数与循环嵌套层数有关,T(n) 是不确定的。通常以最坏时间复杂度来代表算法的时间复杂度。即当 n -> ∞ 时,用T(n)的同阶无穷大表示,记为O(n)。

三种时间复杂度
  • 最坏时间复杂度:最坏情况下,算法执行需要的时间。

  • 平均时间复杂度:算法执行的平均时间。

  • 最好时间复杂度:算法执行的最小时间。

时间复杂度的计算与比较
例1 单层循环
void delay(int n){
	int i=1;
    while(i<=n){
        i++;
    }
}
//指数递增
void delay2(int n){
	int i=1;
    while(i<=n){
        i *= 2;
    }
}

int main(){
    delay(3000);
}

1)计算

  • delay

    • 时间开销与问题规模 n 的关系:T1(n) = 2n+2。
    • 当 n -> ∞ 时,(2n+2) /n = 2,,T(n) 与 n 同阶,所以该算法的时间复杂度为: O(n)
  • delay2

    • 循环中 i 以指数方式递增:2, 4, 8, …, 2x, 直到 2x >= n, 则 x = log2n ,也是循环执行的次数,所以 T2(n) = 2log2n+2。
    • 当 n -> ∞ 时,(2log2n+2) /log2n = 2,,T(n) 与 log2n 同阶,所以该算法的时间复杂度为: O(log2n)

2)比较

​ 当 n -> ∞ 时,log2n/n =(洛必达)= 1/nln2 = 0, 所以 n -> ∞ 的速度远大于 log2n,称 n 为 log2n 的高阶无穷大,称 O(n) 大于 O(log2n) 。

例2 嵌套循环
void delay1(int n){
	int i=1;
    while(i<=n){
        i++;
        j = 0;
        while(j<=n){
            j++;
        }
    }
}

void delay2(int n){
	int i=1;
    while(i<=n){
        i++;
        j = 0;
        while(j<=i){
            j++;
        }
    }
}

int main(){
    delay1(3000);
}

算法 delay1 的 T1(n) = n(3+2n) = 2n2 + 3n

算法 delay2 的 T2(n) = 3n + 2(1+2+3+…+n) = 3n + 2* (1+n)n/2 = n2 +4n

当 n -> ∞ 时,T1(n) /n2 =2,T2(n) /n2 =1,均与 n2 同阶,所以两个算法的时间复杂度均为: O(n2)

常见时间复杂度

由小到大排列:

O(1) < O(log2n)< O(n) < O(nlog2n)< O(n2) < O(n3) < O(2n) < O(n!) < O(nn)

注意:O(1) 表示 T(n)=C (常数)

四则运算

1)加、减法

​ T(n) = T1(n) + T2(n) = O(f(n)) + O(g(n)) = O(max(f(n), g(n)))

​ 减法同理。

​ 口诀:相加取大阶。

2)乘、除法

​ T(n) = T1(n)T2(n) = O(f(n)) O(g(n)) = O(f(n)g(n))

​ 除法同理。

例:

O(n2)+O(n!) = O(n!)

O(n2)O(log2n) = O(nlog2n)

posted @ 2021-10-19 12:01  流水自净  阅读(170)  评论(0编辑  收藏  举报