复杂度分析(上):如何分析、统计算法的执行效率和资源消耗?

1、大 O 复杂度表示法

 1 int cal(int n) {
 2    int sum = 0;
 3    int i = 1;
 4    int j = 1;
 5    for (; i <= n; ++i) {
 6      j = 1;
 7      for (; j <= n; ++j) {
 8        sum = sum +  i * j;
 9      }
10    }
11  }

第 2、3、4 行代码,每行都需要 1 个 unit_time 的执行时间,第 5、6 行代码循环执行了 n 遍,需要 2n * unit_time 的执行时间,第 7、8 行代码循环执行了 n2遍,所以需要 2n2* unit_time 的执行时间。所以,整段代码总的执行时间 T(n) = (2n2+2n+3)*unit_time。用大 O 表示时间复杂度T(n) = O(n2)。

规律:所有代码的执行时间 T(n) 与每行代码的执行次数 n 成正比。

公式: 

含义:T(n) 表示代码执行的时间;n 表示数据规模的大小;f(n) 表示每行代码执行的次数总和。公式中的 O,表示代码的执行时间 T(n) 与 f(n) 表达式成正比。 

定义:大 O 时间复杂度实际上并不具体表示代码真正的执行时间,而是表示代码执行时间随数据规模增长的变化趋势,所以,也叫作渐进时间复杂度(asymptotic time complexity),简称时间复杂度。当 n 很大时,你可以把它想象成 10000、100000。而公式中的低阶、常量、系数三部分并不左右增长趋势,所以都可以忽略。我们只需要记录一个最大量级就可以了,如果用大 O 表示法表示这段代码的时间复杂度,就可以记为: T(n) = O(n2)。

 

2、复杂度分析法则

1)单段代码看高频:比如循环。
2)多段代码取最大:比如一段代码中有单循环和多重循环,那么取多重循环的复杂度。
3)嵌套代码求乘积:比如递归、多重循环等
4)多个规模求加法:比如方法有两个参数控制两个循环的次数,那么这时就取二者复杂度相加。

3、几种常见时间复杂度实例分析

 

多项式阶:随着数据规模的增长,算法的执行时间和空间占用,按照多项式的比例增长。包括,O(1)(常数阶)、O(logn)(对数阶)、O(n)(线性阶)、O(nlogn)(线性对数阶)、O(n2)(平方阶)、O(n3)(立方阶)

非多项式阶:随着数据规模的增长,算法的执行时间和空间占用暴增,这类算法性能极差。包括,O(2n)(指数阶)、O(n!)(阶乘阶)

 

案例:

      1、O(1)  常数阶:一般情况下,只要算法中不存在循环语句、递归语句,即使有成千上万行的代码,其时间复杂度也是Ο(1)。

1  int i = 8;
2  int j = 6;
3  int sum = i + j;

 

    2、O(logn)  对数阶:

1   i=1;
2  while (i <= n)  {
3    i = i * 2;
4  }

第三行代码是循环执行次数最多的,只要能计算出这行代码被执行了多少次,就能知道整段代码的时间复杂度。从代码中可以看出,变量 i 的值从 1 开始取,每循环一次就乘以 2。当大于 n 时,循环结束。还记得我们高中学过的等比数列吗?实际上,变量 i 的取值就是一个等比数列。如果我把它一个一个列出来,就应该是这个样子的:

 

所以,我们只要知道 x 值是多少,就知道这行代码执行的次数了。通过 2x=n 求出x=log2n,所以,这段代码的时间复杂度就是 O(log2n)。但是当n无穷大的时候,忽略对数的“底”,统一表示为 O(logn)。

 

   3、O(nlogn)    线性对数阶:  如果一段代码的时间复杂度是 O(logn),我们循环执行 n 遍,时间复杂度就是 O(nlogn) 了。比如,归并排序、快速排序的时间复杂度都是 O(nlogn)。

 

 4、O(m+n)、O(m*n)   :代码的复杂度由两个数据的规模来决定。如下面的代码时间复杂度就是 O(m+n)。

 1 int cal(int m, int n) {
 2   int sum_1 = 0;
 3   int i = 1;
 4   for (; i < m; ++i) {
 5     sum_1 = sum_1 + i;
 6   }
 7 
 8   int sum_2 = 0;
 9   int j = 1;
10   for (; j < n; ++j) {
11     sum_2 = sum_2 + j;
12   }
13 
14   return sum_1 + sum_2;
15 }
posted @ 2020-02-17 20:09  甘劭  阅读(260)  评论(0编辑  收藏  举报