算法(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億年。