如下四個函數只有兩個爲遞歸python
這裏須要注意一些 fun3和fun4輸出的結果是不同的程序員
fun3:5,4,3,2,1算法
fun4:1,2,3,4,5數據結構
也只有3和4是遞歸app
def hanoi(n , A , B , C): # n 個盤子從A通過B 到C if n >0: hanoi(n-1,A , C ,B) print("%s --->%S"%(A , C)) hanoi(n-1 , B , A ,C ) hanoi(4 , A , B ,C)
時間複雜度:用於體現算法執行時間的快慢,用O表示。通常經常使用的有:幾回循環就爲O(n幾回方) 循環減半的O(logn)dom
空間複雜度:用來評估算法內存佔用大小的一個式子,一般狀況下會選擇使用空間換時間函數
輸入:列表、待查找元素優化
輸出:元素下標或未查找到元素 ui
version 1 順序查找:從列表中的第一個元素開始,順序進行搜索,直到找到爲止,複雜度爲O(n)spa
version 2 二分查找:從有序列表中,經過待查值與中間值比較,以減半的方式進行查找,複雜度爲O(logn)
代碼以下:
list = [1,2,3,4,5,6,7,8,9] element = 7 def ord_sear(list,element): for i in range(0,len(list)): if list[i] == element: print('list[{0}]={1}'.format(i,element)) return i else: print('not found') def bin_sear(list,element): low = 0 high = len(list)-1 while low<=high: mid = (low+high)//2 if element == list[mid]: print('list[{0}]={1}'.format(mid,element)) return mid elif element > list[mid]: low =mid +1 else: high =mid -1 return None i = bin_sear(list,element) j = ord_sear(list,element)
二分查找雖然在時間複雜度上優於順序查找,可是有比較苛刻的條件,即列表必須爲有序的。下面將介紹列表排序:
import time def cal_time(func): def wrapper(*args , **kwargs): t1 = time.time() result = func(*args , **kwargs) t2 = time.time() print("%s running time : %s secs " %(func.__name__ , t2-t1)) return result return wrapper
(思路):首先,列表每倆個相鄰的數,若是前面的比後面的大,那麼交換這倆個數.......
from cal_time import cal_time @cal_time def bubble_sort(li): for i in range(0 , len(li)-1): # i 表示第i趟 有序區有i個數 for j in range(0 , len(li)-i-1): if li[j] > li[j+1]: li[j],li[j+1] = li[j+1] , li[j] import random li = list(range(1000)) random.shuffle(li) bubble_sort(li) print(li)
若是冒泡排序中執行一趟而沒有交換,則列表已是有序狀態,能夠直接結束
def bubble_sort2(li): for i in range(0 , len(li)-1): # i 表示第i趟 有序區有i個數 exchange = False for j in range(0 , len(li)-i-1): if li[j] > li[j+1]: li[j],li[j+1] = li[j+1] , li[j] exchange = True if not exchange: return
一趟遍歷記錄最小的數,放到第一個位置
再一趟遍歷剩下列表中最小的數,繼續放置:
from cal_time import cal_time @cal_time def select_sort(li): for i in range(len(li)-1): # 第i趟 , 有序區li[0:i] 無序區li[i : n] min_loc = i for j in range(i+1, len(li)): if li[min_loc] > li[j]: min_loc = j li[min_loc], li[i] = li[i], li[min_loc] import random li = list(range(10000)) random.shuffle(li) select_sort(li) print(li)
列表被分爲有序區和無序區倆個部分,最初的有序區只有一個元素.
每次無序區選擇一個元素,插入到有序區的位置,直到無序區變空
from cal_time import cal_time @cal_time def insert_sort(li): for i in range(1 , len(li)): # i 既表達趟數, 又表達摸到排的下標 j = i - 1 tmp = li[i] while j >=0 and li[j] > tmp: li[j+1] = li[j] j = j -1 li[j + 1] = tmp import random li = list(range(10000)) random.shuffle(li) insert_sort(li) print(li)
from cal_time import cal_time def _quick_sort(li , left , right): if left < right: mid = partition(li , left , right) _quick_sort(li, left, mid-1) _quick_sort(li, mid+1 , right) @cal_time def quick_sort(li): _quick_sort(li , 0 , len(li)-1) def partition(data , left , right): tmp = data[left] while left < right: while left < right and data[right] >= tmp: right -= 1 data[left] = data[right] while left < right and data[left] <= tmp: left += 1 data[right] = data[left] data[left] = tmp return left import random li = list(range(10000)) random.shuffle(li) quick_sort(li) print(li)
樹是一種數據結構(好比目錄),樹是一種能夠遞歸的數據結構,相關的概念有根節點、葉子節點,樹的深度(高度),樹的度(最多的節點),孩子節點/父節點,子樹等。
在樹中最特殊的就是二叉樹(度不超過2的樹),二叉樹又分爲滿二叉樹和徹底二叉樹,見下圖:
知道了樹就能夠說說堆了,堆分爲大根堆和小根堆,分別的定義爲:一棵徹底二叉樹,知足任一節點都比其孩子節點大或者小。
from cal_time import cal_time def sift(li, low, high): tmp = li[low]# 原省長 i = low j = 2 * i + 1 while j <= high: #第二種退出條件: j > high if j < high and li[j+1] > li[j]: # 若是左孩子存在大於右孩子 j += 1 if tmp < li[j]: li[i] = li[j] i = j j = 2 * i + 1 else: # 第一種退出條件:li[j] <=tmp li[i] = tmp break li[i] = tmp @cal_time def heap_sort(li): n = len(li) #1 建堆 for i in range(n // 2 - 1, -1, -1): sift(li , 0 , i-1) # 2 挨個出數 for i in range(n-1, -1, -1): #i 表示此時堆的high的位置 li[0], li[i] = li[i], li[0] # 退休 + 旗子 sift(li , 0 , i-1) import random li = list(range(10000)) random.shuffle(li) heap_sort(li) print(li)
假設列表中能夠被分紅兩個有序的子列表,如何將這兩個子列表合成爲一個有序的列表成爲歸併
from cal_time import cal_time # 一次歸併 def merge(li , low , mid , high): i = low j = mid + 1 ltmp = [] while i <= mid and j <= high: if li[i] <= li[j]: ltmp.append(li[i]) i += 1 else: ltmp.append(li[j]) j += 1 while i <= mid: ltmp.append(li[i]) i += 1 while j <= high: j += 1 li[low:high+1] = ltmp @cal_time def merge_sort(li, low , high): if low > high: mid = (low + high) // 2 merge_sort(li , low , mid) merge_sort(li,mid+1 , high) merge(li ,low , mid, high)
快排,堆排,歸併的總結: