详解算法的各类复杂度的差异有多大(带图)

作算法分析的时候常常用到各类时间复杂度如O(n), O(logn), O(nlogn), O(n^2), ... 它们之间到底有多大的差异呢?下面这张图是一个直观的表达:算法

可见,各个经常使用的时间复杂度之间都存在着巨大的差别。从O(nlogn)到O(n),从O(n)到O(logn),都是性能上的巨大飞跃。函数

从另外一个角度而言,大于O(n^2)或O(n^3)时间复杂度的程序实际上都是不可用的。根据维基百科,如今最强的CPU每秒大概可执行428亿条指令(4*10^10),而对于一个O(2^n)的程序,当n=100时,就算有2^100条指令,即2^100 = 1.26765 * 10 30条指令。这样的CPU大概要算1万亿年(10^12)。性能

 

算法的运行时间一般与下列函数成比例:spa

 1  大部分程序的大部分指令之执行一次,或者最多几回。若是一个程序的全部指令都具备这样的性质,咱们说这个程序的执行时间是常数。
log log N  能够看做是一个常数:即便N不少,两次去对数以后也会变得很小
 logN  若是一个程序的运行时间是对数级的,则随着N的增大程序会渐渐慢下来,若是一个程序将一个大的问题分解成一系列更小的问题,每一步都将问题的规模缩减成几分之一,通常就会出现这样的运行时间函数。在咱们所关心的范围内,能够认为运行时间小于一个大的常数。对数的基数会影响这个常数,但改变不会太大:当N=1000时,若是基数是10,logN等于3;若是基数是2,logN约等于10.当N=1 00 000,logN只是前值的两倍。当N时原来的两倍,logN只增加了一个常数因子:仅当从N增加到N平方时,logN才会增加到原来的两倍。
N 若是程序的运行时间的线性的,极可能是这样的状况:对每一个输入的元素都作了少许的处理。当N=1 000 000时,运行时间大概也就是这个数值;当N增加到原来的两倍时,运行时间大概也增加到原来的两倍。若是一个算法必须处理N个输入(或者产生N个输出),那么这种状况是最优的。
 NlogN 若是某个算法将问题分解成更小的子问题,独立地解决各个子问题,最后将结果综合起来,运行时间通常就是NlogN。咱们找不到一个更好的形容,就暂且将这样的算法运行时间叫作NlogN。当N=1 000 000时,NlogN大约是20 000 000。当N增加到原来的两倍,运行时间超过原来的两倍,但超过不是太多。
N平方 若是一个算法的运行时间是二次的(quadratic),那么它通常只能用于一些规模较小的问题。这样的运行时间一般存在于须要处理每一对输入数据项的算法(在程序中极可能表现为一个嵌套循环)中,当N=1000时,运行时间是1 000 000;若是N增加到原来的两倍,则运行时间将增加到原来的四倍。
N三次方 相似的,若是一个算法须要处理输入数据想的三元组(极可能表现为三重嵌套循环),其运行时间通常就是三次的,只能用于一些规模较小的问题。当N=100时,运行时间就是1 000 000;若是N增加到原来的两倍,运行时间将会增加到原来的八倍。
2的N次方 若是一个算法的运行时间是指数级的(exponential),通常它很难在实践中使用,即便这样的算法一般是对问题的直接求解。当N=20时,运行时间是1 000 000;若是增加到原来的两倍时,运行时间将是原时间的平方!
相关文章
相关标签/搜索