程序是算法的实际体现,程序可能用各种计算机语言描述,这里采用Python语言描述程序,定义各种数据结构,描述各种算法。
在求解一个问题的具体算法时,需要考虑该算法在求解的过程中需要多少存储空间,需要多少时间。但是在不同的计算机上,时间和空间的基本单元大小可能是不同的,因此需要排除具体机器的个性,抽象的反应算法的共性和本质。
在考虑算法的代价的时候,做这样两个假设:
那么,就可以以具体操作的执行次数作为时间开销的基本度量,以计数值作为存储开销的基本度量。
算法的实际计算代价通常与实际规模(大小)有关,为了处理这种情况,把一个算法的计算开销定义为问题的实力规模函数。即算法分析就是针对一个具体算法,设法确定一种函数关系,以问题实例的某种规模n为参量,反映这个算法在处理规模n的问题实例时需要输出的时间(或空间)代价。
大O记法:假设存在函数g,使得算法A处理规模为n的问题实例所用的时间T(n)=O(g(n)),则称O(g(n))为算法A的渐进时间复杂度,简称时间复杂度,算法的空间复杂度S(n)的定义于此类似。
常用的渐进复杂度函数:
O(1), O(log n), O(n), O(n log n), O(n^2), O(n^3), O(2^n)
算法的复杂度决定了算法的可用性,如果复杂度低,算法就可能用于解决很大的实例,而复杂度很高的算法只能用于很小的实例,可用性很有限。
算法分析的目的是推导出算法的复杂度。
时间复杂度的计算规则:
递归算法的时间复杂度:
def recur(n):
if n == 0:
return g(...)
# do something
for i in range(a):
x = recur(n/b)
# do something
# do something
上面是常见的递归算法模式,这个算法可以归结为a个规模为n/b的子问题。
T(n) = O(n^k) + a * T(n/b)
结论:
T(n) = O(n^(logb (a))), a>b^k
T(n) = O(n^k log n), a = b^k
T(n) = O(n^k), a < b^k
数据之间关联和组合的形式
典型的数据结构有
数据结构上的操作需要通过算法实现