算法复杂度
对于一个给定的问题,我们在设计一个算法时,要计算三项东西,1,从数学角度分析算法的正确性:主要用到形式化证明的方法及相关推理模式,如数学归纳法、循环不变式等。2,分析算法的时间复杂度:一个算法的时间复杂度一定程度上反映了这个算法的好坏,试想一下如果又一个算法需要100亿年才能解决一个问题,会有人用它嘛。3,空间复杂度:一般指的是除开正常内存占用外(比如:排序时要有个数组存放待排序数列)的内存占用。
1,时间频度T(n):一个算法执行的耗费的时间,理论上是算不出来的,必须上机测试才知道,但是因为测试机硬件,编码语言等影响,这个测试时间也不准确,所以我们只需要知道哪个算法花费的时间多,哪个算法花费的时间少就可以了。并且一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法的语句执行次数多,他花费时间就多。一个算法的语句执行次数成为语句频度或者时间频度T(n)。
2,时间复杂度:在钢材提到的时间频度中,n成为问题的规模,当n不断变化时,时间频度T(n)也会不断变化。但有时我们就想知道他变化时呈现什么规律。为此,我们引入时间复杂度概念。一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记做T(n)=O(f(n))为算法的渐进时间复杂度,简称时间复杂度。
在各种不同的算法中,若算法中语句执行次数为一个常数,则时间复杂度为O(1),另外,在时间频度不相同时,时间复杂度有可能相同,如T(n)=3n与T(n)=5n他们的频度不相同,但时间复杂度相同都为O(n)。按数量级递增排列,常见的时间复杂度有:常数阶O(1),对数阶O(log2n),线性阶O(n),线性对数阶O(nlog2n),平方阶O(n2),立方阶O(n3),……k次方阶O(nk),指数阶O(2n),阶乘阶O(n!)。随着问题规模n的不断增大,上述时间复杂度不断增大,算法的执行效率越低。
常见的算法时间复杂度由小到大依次为:O(1)<O(log2n)<O(n)<O(nlog2n)<O(n2)<O(n3)<O(nk)<O(2n)<O(n!)
3,空间复杂度:类似于时间复杂度,一个算法的空间复杂度S(n)定义为该算法所耗费的存储空间,他也是问题规模n的函数。我们一般讨论的是除正常占用内存外的辅助存储单元规模
4,八种排序算法的时间复杂度比较
排序算法 | 时间复杂度 | 最差情况 | 稳定性 | 空间复杂度 | 备注 |
冒泡排序 | O(n2) | O(n2) | 稳定 | S(1) | n小时较好 |
选择排序 | O(n2) | O(n2) | 不稳定 | S(1) | n小时较好 |
插入排序 | O(n2) | O(n2) | 稳定 | S(1) | 大部分已排序时较好 |
交换排序 | O(n2) | O(n2) | 不稳定 | S(1) | n小时较好 |
shell排序 | O(nlog2n) | O(ns)1<s<2 | 不稳定 | S(1) | s是所选分组 |
快速排序 | O(nlog2n) | O(n2) | 不稳定 | S(nlog2n) | n大时较好 |
归并排序 | O(nlog2n) | O(nlog2n) | 稳定 | S(1) | n大时较好 |
堆排序 | O(nlog2n) | O(nlog2n) | 不稳定 | S(1) | n大时较好 |