确定一种标准和确定的方法来确定算法的性能(速度和内存来确定算法的性能)。
1.大O表示法
一个算法的增长速率或者一个算法的增长规律非常重要,因为当输入数据量变得无穷大时,它可以用来描述算法的效率到底有多高。O表示法正是这样一种表示算法增长规律的方法。我们通常使用算法的最坏情况复杂度,记为T(n),定义为任何大小的输入n所需的最大运行时间。
O表示法的几点规则:
- 常数项用O(1)表示
- 常量因子往往被忽略
- 加法法则:取量级最大的那个
- 乘法法则:对于一个循环,假设循环体的时间复杂度为O(n),循环次数为m,则这个循环的时间复杂度为O(n×m)。
简言之,如果一个算法的执行次数是T(n),那么只保留最高次项,同时忽略最高项的系数后得到函数f(n),此时算法的时间复杂度就是O(f(n))。
O法的例子及工作原理
…
2.时间复杂度
定义:算法的时间复杂度O(n)是一个函数,它定性描述该算法的运行时间。这是一个代表算法输入值的字符串的长度函数。假设T(n)表示算法的运行时间,它的复杂度O(n)并没有具体表明运行此算法实际需要多少时间。
常见的复杂度量级
举例:求该算法的时间复杂度
List = [n]
for (i=0, i++, i<n){
for (j=i+1, j++, j<n){
for (k=j+1, k++, k<n){
printf(“Hello world”)
}
}
}
i=0, j=1, k=2,3,4,5…n-1 =>n-2
i=0, j=2, k=3,4,5…n-1 =>n-3
…
i=0, j=n-2, k=n-1 =>1
sum_0=1+2+…+n-2=(n-2)(n-1)/2
i=1, j=2, k=3,4,5…n-1
i=1, j=3, k=4,5…n-1
…
i=1, j=n-2, k=n-1
sum_1=1+2+…+n-3=(n-3)(n-2)/2
….
sum_n-2=1+2
sum_n-3=1
SUM = sum_0+ sum_1+…+ sum_n-2+ sum_n-3
计算菲波那切数列的时间复杂度:
def aFunc(n):
if (n<=1):
return 1
else:
return aFunc(n-1) +aFunc(n-2)
通过归纳证明法可以证明,当 n >= 1 时 T(n) < (5/3)^n,同时当 n > 4 时 T(n) >= (3/2)^n。
所以该方法的时间复杂度可以表示为 O((5/3)^n),简化后为 O(2^n)
除了考虑算法的复杂度之外,我们还需要考虑一些其他的因素。一个高效的实现并不能总是影响算法的复杂度,但它可以降低常量因素的影响,从而使算法在实际应用中更加高效。
3.空间复杂度
算法的空间复杂度:定义为该算法所耗费的存储空间,它也是问题规模n的函数。渐进空间复杂度也常常称为空间复杂度。一个算法在计算机存储器上所占用的存储空间,包括存储器算法本身所占用的存储空间,算法的输入输出数据所占用的存储空间和算法在运行过程中临时占用的存储空间这三个方面。