研究复杂度的根本目的是为了降低复杂度,在时间复杂度和空间复杂度之间权衡出一个最佳解决方案。算法复杂度是什么?
是指算法在编写成可执行程序后,运行所需的内存资源和时间资源,主要通过时间复杂度和空间复杂度来表示。算法的复杂性体现在运行该算法时的计算机所需资源多少上,而计算机资源最重要的是时间和空间(寄存器)资源,因此分为空间复杂度和时间复杂度。
时间复杂度是什么?
是一个定性的描述算法运行时间的函数;是代表算法输入值的字符串的长度的函数(该句来自wiki pedia)
空间复杂度是什么?
是对一个算法在运行过程中临时占用存储空间大小的度量,即问题规模n的函数。如何表示时间复杂度?
时间复杂度一般用O表示,不包括该复杂度函数的低阶项和系数项。也就是说,如果一个算法的时间复杂度是O(n)=5n3+ 3n,那么它的复杂度是O(n3)如何表示空间复杂度
我们一般讨论的也是渐进空间复杂度,记作S(n)=O(f(n)),比如直接插入排序的时间复杂度是O(n^2),空间复杂度是O(1),递归算法的空间复杂度是O(n),因为每次递归都要返回数据。
当使用O(n)这种方式表示时间复杂度时,更多的是对真正的时间复杂度的一种渐进,模拟的是n趋于无穷大时的复杂度。如何计算时间复杂度
1、估计算法的操作单元数量,每个单元的运行时间都相同。总运行时间和算法的操作单元数量最多差一个常量系数。
2、相同数量级的不同输入值也可能造成算法运行时间不同,所以用算法的最坏情况复杂度T(n),定义为任何大小的输入n所需要的最大时间(上界)
3、一个算法中某个语句的执行次数叫做语句频度或者时间频度,记为T(n)
4、几种时间复杂度:
常数时间:如果对于一个算法,T(n)的上界与输入大小无关,则称其具有常数时间,记作O(1),如访问数组内的单个元素。
线性时间:如果需求是找到无序数组中的最小元素,因为需要遍历所有元素来找到最小值,是一个线性时间操作,记作O(n)
对数时间:计算机采用二进制计数,所以对数一般以2为底。由于不同的对数公式只有底数不同,而且都是常数,所以O计法中将这个底数抛弃,记为O(logn),常见的有二叉树相关操作和二分搜索。对数时间中每增加一个输入,所需额外计算时间变小。
指数时间:一个问题求解所需要的计算时间n随着n的增加呈指数型增长
此外还有,多项式时间、比指数时间快,比多项式时间慢的超多项式时间或者叫做次指数时间、双重指数时间等等。
分析算法时常用的函数分类列表如何计算空间复杂度?
空间复杂度的计算主要考虑三个方面:存储算法本身所占的存储空间
算法的输入输出数据所占用的存储空间
算法在运行过程中临时占用的存储空间
其中,算法的输入输出数据是由要解决的问题决定的,通过参数表由调用函数传递而来,不随着算法的不同而改变。
存储算法本身所用的存储空间与算法长度成正比,要压缩这部分就要写出较短的代码
算法在运行过程中所临时占用的空间有的是不随着问题解决规模的扩大而扩大的,也就是“就地”的,节省存储的。也有的占用的临时工作单元跟解决问题的规模有关,如快速排序和归并排序算法。
在写算法时,若是写成递归算法,运行时需要多加一个附加堆栈,占用较多的临时工作单元,如果写成非递归算法,可能算法本身会很长,具体情况具体权衡。
总体而言,一个算法的空间复杂度只考虑运行过程中为局部变量分配的存储空间的大小,包括:参数表中形参变量分配的存储空间
函数体中定义的局部变量分配的存储空间
如果一个算法是递归的,那么空间复杂度是递归所使用的堆栈空间大小,即:
一次调用所分配的临时存储空间大小 * 被调用的次数
算法的空间复杂度一般也以数量级的方式给出。