數據結構與算法
算法
衡量算法的標準:
時間複雜度:程序執行的大概次數;O(1),O(n),O(logn),O(n^2)等
空間複雜度
排序算法
冒泡排序:
def BubbleSort(li): # 每一次生成一個最大值 for i in range(len(li)): #### i = 0 i = 1 --- 8 flag = False # 已生成最大值的便不用再遍歷,且每次最後一個數不用 for j in range(len(li)-i-1): ### j = 0, 1, 2, 3, 7 if li[j] > li[j+1]: ### li[0] > li[1] | li[1] > li[2] | li[2] > li[3] li[j], li[j+1] = li[j+1], li[j] #### [5,4,6,7,3,8,2,1,9] flag = True if not flag: return
選擇排序:
def selectSort(li): # 每次循環得到一個最小的數 for i in range(len(li)): # minLoc = i = 0 for j in range(i+1, len(li)): # j = 1, j = 2 if li[j] < li[i]: ### li[2] < li[minLoc] 4 < 5 li[j], li[i] = li[i], li[j] ## [5,7,4,6,3,8,2,9,1]
插入排序:
def insertSort(li): for i in range(1, len(li)): tmp = li[i] ## tmp = li[1] = 5 j = i - 1 ## j = 1 - 1 = 0 while j >= 0 and li[j] > tmp: ## li[0] = 7 > 5: li[j+1] = li[j] ## li[1] = li[0] = 7 ==> [7,7,4,6,3,8,2,9,1] j = j - 1 ## j = -1 li[j+1] = tmp ### li[0] = tmp = 5 ==> [5,7,4,6,3,8,2,9,1]
快速排序:
### 快排:O(n) def partition(li, left, right): tmp = li[left] while left < right: # 滿足循環,左移;不滿足條件時候,不進循環 while left < right and li[right] >= tmp: # 從右往左 right = right - 1 li[left] = li[right] # 滿足循環,右移;不滿足循環,不進循環 while left < right and li[left] <= tmp: left = left + 1 li[right] = li[left] # 指針重合,left,right均可以,爲對稱使用left li[left] = tmp return left ## 時間複雜度: O(nlogn) def _quickSort(li, left, right): if left < right: mid = partition(li, left, right) ### O(n) _quickSort(li, left, mid - 1) ### O(logn) _quickSort(li, mid + 1, right)
歸位排序:
### 時間複雜度: O(nlogn) def merge(li, low, mid, right): i = low j = mid + 1 ltmp = [] while i <= mid and j <= right: if li[i] < li[j]: ltmp.append(li[i]) i = i + 1 else: ltmp.append(li[j]) j = j + 1 while i <= mid: ltmp.append(li[i]) i = i + 1 while j <= right: ltmp.append(li[j]) j = j + 1 li[low:right+1] = ltmp def mergeSort(li, low, high): if low < high: mid = (low + high) // 2 mergeSort(li, low, mid) mergeSort(li, mid + 1, high) print('歸併之前:', li[low:high+1]) merge(li, low, mid, high) print('歸併之後:', li[low:high + 1])
計數排序:
def countSort(li): count = [0 for i in range(11)] for index in li: count[index] += 1 li.clear() for index, val in enumerate(count): print(index, val) for i in range(val): li.append(index) li = [10,4,6,3,8,4,5,7] countSort(li) print(li)
貪婪算法:
# 分糖果原則:貪婪算法 '''貪心規律 (1)某個糖果不能滿足某個孩子,那麼,該糖果一定不能滿足更大需求因子的孩子。 (2)某個孩子可以用更小的糖果滿足,則沒必要用更大的糖果,留着更大的糖果去滿足需求因子更大的孩子。(貪心!!) (3)孩子的需求因子更小則其更容易被滿足,故優先從需求因子小的孩子開始,因爲用一個糖果滿足一個較大需求因子的孩子或滿足較小需求因子的孩子效果一樣。(最終總量不變)(貪心!!) 算法思路 (1)對需求因子數組g和糖果大小數組s進行從小到大排序; (2)按照從小到大的順序使用各糖果,嘗試是否可以滿足某個孩子,每個糖果只嘗試一次;若成功,則換下一個糖果嘗試;直到發現沒有孩子或者沒有糖果,循環結束。 --------------------- ''' def candygivechildren(g, s): g = sorted(g) s = sorted(s) child = 0 cookie = 0 while child < len(g) and cookie < len(s): if g[child] < s[cookie]: child += 1 cookie += 1 return child g = [5,10,2,9,15,9] s = [1,3,6,8,20] res = candygivechildren(g,s) print(res)
數據結構
線性結構:
數組:必須是連續的內存空間
鏈表:內存空間不連續
class Hero(object): def __init__(self, no=None, name=None, nickname=None, pNext=None): self.no = no self.name = name self.nickname = nickname self.pNext = pNext def add(head, hero): ### 後面添加 # head.pNext = hero # 將指針賦值給一個變量 cur = head # print(id(cur), id(head)) while cur.pNext != None: if cur.pNext.no > hero.no: break cur = cur.pNext hero.pNext = cur.pNext cur.pNext = hero # print(id(cur), id(head)) def showAll(head): cur = head while cur.pNext != None: cur = cur.pNext print(cur.no, cur.name) def delHero(head, no): cur = head while cur.pNext != None: if cur.pNext.no == no: break cur = cur.pNext ### cur += 1 cur.pNext = cur.pNext.pNext head = Hero() h1 = Hero(1, '宋江', '及時雨') add(head, h1) h2 = Hero(2, '盧俊義', '玉麒麟') add(head, h2) h4 = Hero(4, '魯智深', '花和尚') add(head, h4) h3 = Hero(3, '林沖', '豹子頭') add(head, h3) showAll(head)
非線性結構:
樹