首页 > 代码库 > 数据结构——时间复杂度

数据结构——时间复杂度

分析算法的时间复杂度:

算法的时间复杂度就是反应了程序执行时间随着输入规模增长而增长的量级,这个标准可以很好的反映出算法的优劣性质。

算法的频度:

一个算法执行所耗费的时间完全可以以程序执行的次数进行估算,程序执行的次数越多,时间复杂度也就越复杂,也就是说算法花费的时间与算法中语句执行的次数成正比例,因此,一个算法中语句执行的次数可以叫做时间频度。记为T(n)。

时间复杂度:

 

由于n表示规模,当n不断变化的时候,T(n)也会随之不断变化,当我们需要知道他的变化趋势的时候,就要引入时间复杂度。一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作T(n)=O(f(n)),称O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度。(引用概念解释)

常见的时间复杂度有:常数阶O(1),对数阶O(log2n),线性阶O(n), 线性对数阶O(nlog2n),平方阶O(n2),立方阶O(n3),..., k次方阶O(nk),指数阶O(2n)。随着问题规模n的不断增大,上述时间复杂度不断增大,算法的执行效率越低。

时间复杂度的求解步骤:

1.找到算法的基本语句;(就是执行次数最多的那个语句,通常将最内层循环的循环体作为基本语句)

2.计算基本语句执行次数的数量级;(由于时间复杂度本就是一个估算的过程,只需要关注走向影响最大,即基本语句执行次数的函数的最高次幂正确即可,其余忽略,简化算法分析,只需要集中在一点:“增长率“”上即可)

3.表示算法的时间复杂度;(算法中,若循环中出现嵌套循环,则基本语句一般为最内层循环体;若是并列循环,则并列循环的时间复杂度相加即可)如:

1 for (i=1; i<=n; i++)  ⑴
2        x++;  
3 for (i=1; i<=n; i++)      ⑵
4      for (j=1; j<=n; j++)    
5           x++;  

第一个循环时间复杂度为O(n),第二个循环时间复杂度为O(n2),整个算法的时间复杂度为Ο(n+n2)=Ο(n2)

注解:Ο(1)表示基本语句的执行次数是一个常数,一般来说,只要算法中不存在循环语句,其时间复杂度就是Ο(1)。

2个重要法则:

求和法则:若算法的2个部分时间复杂度分别为 T1(n)=O(f(n))和 T2(n)=O(g(n)),则 T1(n)+T2(n)=O(max(f(n), g(n)))   max()表示取最高数量级
特别地,若T1(m)=O(f(m)), T2(n)=O(g(n)),则 T1(m)+T2(n)=O(f(m) + g(n))     数量级相同,类似并列循环

乘法法则: 是指若算法的2个部分时间复杂度分别为 T1(n)=O(f(n))和 T2(n)=O(g(n)),则 T1*T2=O(f(n)*g(n))  一般表示循环嵌套

总结:简单分析一下,一般来说,对于顺序结构和判断语句,时间复杂度一般为O(1)或者使用“求和法则”,而对于循环结构,循环语句的运行时间主要体现在多次迭代中执行循环体以及检验循环条件的时间耗费,一般可用"乘法法则"。对于特别复杂的算法,则可以将之分为几个容易估算的算法,最后利用乘法和求和法则进行规整求出时间复杂度。

 

时间复杂度举例:

O(1):交换i,j的值

1 tmp = i;
2 i = j;
3 i = tmp;

O(n):

1 a=0;  
2   b=1;                      ①  
3   for (i=1;i<=n;i++) ②  
4   {    
5      s=a+b;    ③  
6      b=a;     ④    
7      a=s;     ⑤  
8   }  

语句1的频度:2
语句2,3,4,5的频度:n,
T(n)=4n+2=O(n).

O(n2):

1 for (i=1;i<n;i++) 
2 { 
3 y=y+1; ① 
4 for (j=0;j<=(2*n);j++) 
5 x++; ② 
6 }

首先从内层循环分析,基本语句为2,内层执行了2*n+1次,在外层循环了n-1次,利用乘法原理(是嵌套不是并列), 语句2的频度是(n-1)*(2n+1)=2n2-n-1,故O(n)=n2(只需要取除去系数数量级高的那一项)

O(n3):

1 for(i=0;i<n;i++)  
2    {    
3       for(j=0;j<i;j++)    
4       {  
5          for(k=0;k<j;k++)  
6             x=x+2;    
7       }  
8    }  

方法同O(n2)

O(log2 n):

1 int num1, num2;
2 for(int i=0; i<n; i++){ 
3     num1 += 1;
4     for(int j=1; j<=n; j*=2){ 
5         num2 += num1;
6     }
7 }

j每循环一次乘了2.
j初始为 1,所以循环 x 次之后 j=2x.
j > n 时停止循环,也就是 2x > n,此时x=log2n
故循环了log2n次(x表示次数)

技术分享

 

时间复杂度决定了一个算法的效率,较为简单的如O(C),O(n),O(nk),O(log2n)算法效率还算比较高,如果是O(2n),O(n!)则规模n稍微增加,算法就会死掉!

 

数据结构——时间复杂度