算法(Algorithm):一个计算过程,解决问题的方法。python
Niklaus Wirth说:“程序=数据结构+算法”算法
算法是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法表明着用系统的方法描述解决问题的策略机制。也就是说,可以对必定规范的输入,在有限时间内得到所要求的输出。若是一个算法有缺陷,或不适合于某个问题,执行这个算法将不会解决这个问题。不一样的算法可能用不一样的时间、空间或效率来完成一样的任务。一个算法的优劣能够用空间复杂度与时间复杂度来衡量。数据结构
一个算法应该具备如下七个重要的特征:分布式
时间复杂度:就是用来评估算法运行时间的一个式子(单位)。通常来讲,时间复杂度高的算法比复杂度低的算法慢。函数
类比生活的一些时间,估计时间:性能
来讲说下面这些代码的时间复杂度是多少呢?spa
print('Hello World') # O(1) for i in range(n): # O(n) print('Hello World') for i in range(n): # O(n^2) for j in range(n): print('Hello World') for i in range(n): # O(n^3) for j in range(n): for k in range(n): print('Hello World') while n > 1: # O(log2n)或者O(logn) print(n) n = n // 2
当算法过程当中出现循环折半的时候,复杂度式子中会出现logn。3d
大O简而言之能够认为它的含义是“order of”(大约是)。对象
Ο(1)<Ο(log2n)<Ο(n)<Ο(nlog2n)<Ο(n2)<O(n2logn)< Ο(n^3)<…<Ο(2^n)<Ο(n!)blog
例如:
由图中咱们能够看出,当 n 趋于无穷大时, O(nlogn) 的性能显然要比 O(n^2) 来的高
通常来讲,只要算法中不存在循环语句,其时间复杂度就是 O(1)。
而时间复杂度又分为三种:
最差时间复杂度的分析给了一个在最坏状况下的时间复杂度状况,这每每比平均时间复杂度好计算,而最优时间复杂度通常没什么用,由于没人会拿一些特殊状况去评判这个算法的好坏。
复杂状况根据算法执行过程来判断。
空间复杂度:用来评估算法内存占用大小的式子。
算法使用了几个变量:O(1)
算法使用了长度为n的一维列表:O(n)
算法使用了m行n列的二维列表:O(mn)
算法宁肯占用更多的内存也要让时间变快,分布式的运算也是一个空间换时间的过程。
由这两个特色判断函数是不是合法的递归:
# 没有结束条件不是合法的递归 def func1(x): print(x) func1(x-1) # 结束条件结束不了,不是合法的递归 def func2(x): if x>0: print(x) func2(x+1) # 合法的递归: 先打印后递归 def func3(x): if x>0: print(x) func3(x-1) func3(5) # 5 4 3 2 1 # 合法的递归:先递归后打印,所以先打印最里层的 1 def func4(x): if x>0: func4(x-1) print(x) func4(5) # 1 2 3 4 5
大焚天创造世界的时候作了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序从新摆放到另外一根柱子上。在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。64根柱子移动完毕之日就是世界毁灭之时。
n个盘子时:
将n-1个盘子看作一个总体,把最后一个盘子看作一个总体。
将n-1个盘子从A经C移动到B:
把第n个盘子从A移动到C:
把n-1个小圆盘从B通过A移动到C:
能够看到第一步、第三步就是比原问题规模小一的一样问题,所以就是原问题递归的一个子问题。
def hanoi(n, a, b, c): """ 汉诺塔问题 :param n: 问题规模 :param a: 从哪一个柱子 :param b: 经哪一个柱子 :param c: 到哪一个柱子 :return: """ if n > 0: hanoi(n-1, a, c, b) # 将n-1个盘子从a通过c移动到b print("moving from %s to %s" % (a, c)) # 将剩余的最后一个盘子从a移动到c hanoi(n-1, b, a, c) # 将n-1个盘子从b通过a移动到c n = int(input('请输入汉诺塔的层数:')) hanoi(n, "A柱", "B柱", "C柱") """ 请输入汉诺塔的层数:3 moving from A柱 to C柱 moving from A柱 to B柱 moving from C柱 to B柱 moving from A柱 to C柱 moving from B柱 to A柱 moving from B柱 to C柱 moving from A柱 to C柱 """
汉诺塔移动次数的递推式:h(x)=2h(x-1)+1。
h(64)=18446744073709551615
假设婆罗门每秒搬一次盘子,总共须要5800亿年。