1.python數據結構及算法基礎學習筆記思惟導圖node
2.程序代碼演示python
1.鏈表模型:linklist.py算法
1 """ 2 功能: 實現單鏈表的構建和操做 3 4 """ 5 6 # 建立節點類 7 class Node: 8 """ 9 思路 : *自定義類視爲節點類,類中的屬性爲數據內容 10 *寫一個next屬性,用來和下一個 節點創建關係 11 """ 12 def __init__(self,val,next = None): 13 """ 14 val: 有用數據 15 next: 下一個節點引用 16 """ 17 self.val = val 18 self.next = next 19 20 21 # 鏈式線性表操做類 22 class LinkList: 23 """ 24 思路 : 生成單鏈表,經過實例化的對象就表明一個鏈表 25 能夠調用具體的操做方法完成各類功能 26 """ 27 def __init__(self): 28 # 鏈表的初始化節點,沒有有用數據,可是便於標記鏈表的開端 29 self.head = Node(None) 30 31 # 初始化鏈表,添加一組節點 32 def init_list(self,list_): 33 p = self.head # p 做爲移動變量 34 for i in list_: 35 # 遍歷到一個值就建立一個節點 36 p.next = Node(i) 37 p = p.next 38 39 # 遍歷鏈表 40 def show(self): 41 p = self.head.next # p表明第一個有值的節點 42 while p is not None: 43 print(p.val) 44 p = p.next # p向後移動 45 46 # 判斷鏈表爲空 47 def is_empty(self): 48 if self.head.next is None: 49 return True 50 else: 51 return False 52 53 # 清空鏈表 54 def clear(self): 55 self.head.next = None 56 57 # 尾部插入 58 def append(self,val): 59 p = self.head 60 # p移動到最後一個節點 61 while p.next is not None: 62 p = p.next 63 p.next = Node(val) # 最後添加節點 64 65 # 頭部插入 66 def head_insert(self,val): 67 node = Node(val) 68 node.next = self.head.next 69 self.head.next = node 70 71 # 指定位置插入 72 def insert(self,index,val): 73 # 設置個p 移動到待插入位置的前一個 74 p = self.head 75 for i in range(index): 76 # 若是index超出了最大範圍跳出循環 77 if p.next is None: 78 break 79 p = p.next 80 # 插入節點 81 node = Node(val) 82 node.next = p.next 83 p.next = node 84 85 # 刪除節點 86 def remove(self,val): 87 p = self.head 88 # p 移動,待刪除節點上一個 89 while p.next is not None and p.next.val != val: 90 p = p.next 91 92 if p.next is None: 93 raise ValueError("x not in linklist") 94 else: 95 p.next = p.next.next 96 97 98 # 獲取某個節點的值 (經過索引獲取) 99 def search(self,index): 100 if index < 0: 101 raise IndexError("index out of range") 102 103 p = self.head.next 104 # 循環移動p 105 for i in range(index): 106 if p is None: 107 raise IndexError("index out of range") 108 p = p.next 109 return p.val 110 111 112 if __name__ == "__main__": 113 # 想有一個鏈表 114 link = LinkList() 115 # 初始化一組數據 116 l = [1,2,3,4] 117 link.init_list(l) 118 # link.clear() 119 print(link.search(0)) 120 # 鏈表遍歷 121 # link.show() 122 # link.insert(2,88) 123 # link.show() 124 # link.clear() 125 # print(link.is_empty()) 126 # Abby = Node((1,'Abby',18,'w')) 127 # Emma = Node((2,'Emma',17,'w')) 128 # Alex = Node((3,'Alex',19,'m')) 129 # Abby.next = Emma 130 # Emma.next = Alex
2.棧的順序存儲:sstack.py數據結構
""" 棧模型的順序存 思路 : 1. 順序存儲可使用列表實現,可是列表功能豐富,不符合棧模型要求 2. 將列表功能封裝,實現順序棧的類,只提供棧的操做功能 功能: 出棧, 入棧,判斷棧空,查看棧頂元素 """ # 自定義異常 class StackError(Exception): pass # 順序棧 class SStack: def __init__(self): # 空列表就是棧的存儲空間 # 列表的最後一個元素做爲棧頂元素 self.__elems = [] # 入棧 def push(self,val): self.__elems.append(val) # 判斷棧空 def is_empty(self): return self.__elems == [] # 出棧 def pop(self): if self.is_empty(): raise StackError("pop from empty stack") return self.__elems.pop() # 查看棧頂 def top(self): if self.is_empty(): raise StackError("pop from empty stack") return self.__elems[-1] if __name__ == '__main__': st = SStack() st.push(10) st.push(20) st.push(30) while not st.is_empty(): print(st.pop()) st.pop()
3.棧的鏈式存儲:lstack.pyapp
1 """ 2 棧的鏈式模型 3 4 思路: 5 1. 經過節點存儲數據達到鏈式存儲的目的 6 2. 封裝方法,實現棧的基本操做(入棧,出棧,棧空,查看棧頂) 7 3. top爲棧頂,在鏈表的頭做爲棧頂位置 (不準要遍歷) 8 """ 9 10 # 自定義異常 11 class StackError(Exception): 12 pass 13 14 # 節點類 15 class Node: 16 def __init__(self,val,next = None): 17 self.val = val 18 self.next = next 19 20 # 鏈式棧模型 21 class LStack: 22 def __init__(self): 23 # top做爲棧頂的標記 24 self.__top = None 25 26 def is_empty(self): 27 return self.__top is None 28 29 # 入棧 30 def push(self,val): 31 self.__top = Node(val,self.__top) 32 33 # node = Node(val) 34 # node.next = self.__top 35 # self.__top = node 36 37 # 出棧 38 def pop(self): 39 if self.__top is None: 40 raise StackError("pop from empty stack") 41 data = self.__top.val 42 self.__top = self.__top.next 43 return data 44 45 # 查看棧頂元素 46 def top(self): 47 if self.__top is None: 48 raise StackError("pop from empty stack") 49 return self.__top.val 50 51 52 if __name__ == '__main__': 53 ls = LStack() 54 ls.push(10) 55 ls.push(20) 56 ls.push(30) 57 print(ls.pop()) 58 print(ls.pop())
4.隊列的順序存儲:squeue.py函數
1 """ 2 隊列的順序存儲 3 4 思路 : 5 1. 基於列表完成數據存儲 6 2. 對列表功能進行封裝 7 3. 列表的頭部做爲隊頭,尾部做爲隊尾 8 功能: 入隊(enqueue),出隊(dequeue),判斷隊列爲空 9 """ 10 11 # 自定義異常 12 class QueueError(Exception): 13 pass 14 15 class SQueue: 16 # 設置空列表做爲隊列存儲空間 17 def __init__(self): 18 self.__elems = [] 19 20 # 判斷隊列是否爲空 21 def is_empty(self): 22 return self.__elems == [] 23 24 # 入隊 25 def enqueue(self,val): 26 self.__elems.append(val) 27 28 # 出對 29 def dequeue(self): 30 if not self.__elems: 31 raise QueueError("Queue is empty") 32 return self.__elems.pop(0) 33 34 if __name__ == '__main__': 35 sq = SQueue() 36 37 sq.enqueue(10) 38 sq.enqueue(20) 39 sq.enqueue(30) 40 41 while not sq.is_empty(): 42 print(sq.dequeue())
5.隊列的鏈式存儲:lqueue.pypost
1 """ 2 鏈式隊列 3 4 思路: 5 1. 基於鏈表構建隊列模型 6 2. 鏈表的開端做爲隊頭, 結尾做爲隊尾 7 3. 對頭隊尾分別添加標記,避免每次插入數據都遍歷鏈表 8 4. 隊頭和隊尾重疊時認爲隊列爲空 9 """ 10 11 # 自定義異常 12 class QueueError(Exception): 13 pass 14 15 # 節點類 16 class Node: 17 def __init__(self,val,next = None): 18 self.val = val 19 self.next = next 20 21 # 隊列操做 22 class LQueue: 23 def __init__(self): 24 # 定義隊頭,隊尾 25 self.front = self.rear = Node(None) 26 27 def is_empty(self): 28 return self.front == self.rear 29 30 # 如隊 rear動 31 def enqueue(self,val): 32 self.rear.next = Node(val) 33 self.rear = self.rear.next 34 35 # 出隊 front動 36 def dequeue(self): 37 if self.front == self.rear: 38 raise QueueError("Queue is empty") 39 40 # front移動到的節點已經出隊 41 self.front = self.front.next 42 return self.front.val 43 44 if __name__ == '__main__': 45 lq = LQueue() 46 lq.enqueue(10) 47 lq.enqueue(20) 48 lq.enqueue(30) 49 print(lq.dequeue())
6.遞歸函數:recursion.py學習
1 """ 2 求一個數的階乘 n! 3 """ 4 5 def fun(n): 6 result = 1 7 for i in range(1, n + 1): 8 result *= i 9 return result 10 11 12 def recursion(n): 13 if n <= 1: 14 return 1 15 return n * recursion(n - 1) 16 17 18 print(fun(5)) 19 print(recursion(5))
7.二叉樹的鏈式存儲:btree.pyui
1 """ 2 二叉樹的遍歷實踐 3 4 思路分析: 5 1. 使用鏈式結構存儲二叉樹的節點數據 6 2. 節點中存儲 數據, 左孩子連接,右孩子連接 三個屬性 7 """ 8 from squeue import * 9 10 # 二叉樹節點類 11 class Node: 12 def __init__(self,val,left=None,right=None): 13 self.val = val 14 self.left = left 15 self.right = right 16 17 # 二叉樹遍歷方法 18 class Bitree: 19 def __init__(self,root): 20 self.root = root 21 22 # 先序遍歷 23 def preOrder(self,node): 24 if node is None: 25 return 26 print(node.val) 27 self.preOrder(node.left) 28 self.preOrder(node.right) 29 30 # 中序遍歷 31 def inOrder(self, node): 32 if node is None: 33 return 34 self.inOrder(node.left) 35 print(node.val) 36 self.inOrder(node.right) 37 38 # 後序遍歷 39 def postOrder(self, node): 40 if node is None: 41 return 42 self.postOrder(node.left) 43 self.postOrder(node.right) 44 print(node.val) 45 46 # 層次遍歷 47 def levelOrder(self,node): 48 """ 49 node先入隊,循環判斷,隊列不爲空時,出隊表示遍歷, 50 同時讓出隊元素的左右孩子入隊 51 """ 52 sq = SQueue() 53 sq.enqueue(node) 54 while not sq.is_empty(): 55 node = sq.dequeue() 56 print(node.val) # 遍歷元素 57 if node.left: 58 sq.enqueue(node.left) 59 if node.right: 60 sq.enqueue(node.right) 61 62 63 64 if __name__ == '__main__': 65 b = Node('B') 66 f = Node('F') 67 g = Node('G') 68 d = Node('D',f,g) 69 h = Node('H') 70 i = Node('I') 71 e = Node('E',h,i) 72 c = Node('C',d,e) 73 a = Node('A',b,c) # 整個樹根 74 75 bt = Bitree(a) # 把a做爲根節點進行遍歷 76 77 bt.preOrder(bt.root) 78 print("========================") 79 bt.inOrder(bt.root) 80 print("========================") 81 bt.postOrder(bt.root) 82 print("========================") 83 bt.levelOrder(bt.root)
8.排序算法選擇、冒泡、插入、歸併、快速排序:sort.pyspa
1 def selection_sort(arr): 2 """ 3 1.選擇排序:外層循環一次,就可排好一個數,從前日後排。 4 用選定元素與其後的全部元素進行比較,較大(小)交換 5 """ 6 for i in range(len(arr) - 1): # 須要比較n-1輪 7 for j in range(i + 1, len(arr)): # 每一輪須要比較j次 8 if arr[i] > arr[j]: # 升序排列 9 arr[i], arr[j] = arr[j], arr[i] 10 11 12 def buble_sort(arr): 13 """ 14 2.冒泡排序:外層循環一次,就可排好最後一個數,從後往前排。 15 全部相鄰元素依次進行比較,較大(小)交換 16 """ 17 for i in range(len(arr) - 1): # 須要比較n-1輪 18 for j in range(len(arr) - 1 - i): # 每輪比較中,索引j的取值0到(n-1)-i 19 if arr[j] > arr[j + 1]: 20 arr[j], arr[j + 1] = arr[j + 1], arr[j] 21 22 23 def insert_sort(arr): 24 """ 25 3.插入排序:將第一個元素看作有序序列,從後向前掃描有序序列,將爲排序元素依次插入對應位置 26 """ 27 for i in range(1, len(arr)): # 只須要對第二個到最後一個元素進行排序 28 preindex = i - 1 29 current = arr[i] 30 while preindex >= 0 and arr[preindex] > current: 31 arr[preindex + 1] = arr[preindex] # 將前一個元素賦值給當前元素位置上 32 preindex -= 1 33 arr[preindex + 1] = current # 將當前元素賦值給「對應」位置上 34 35 36 def merge_sort(arr): 37 """ 38 4.歸併排序:遞歸的將arr一分爲二的拆分爲一個二叉樹(每一個葉子節點只有一個數), 39 定義空列表result=[],迴歸的將葉子結點合併到result中,迴歸到根節點 40 """ 41 if len(arr) < 2: 42 return arr # 遞歸結束條件:拆分後的最終列表中只有一個元素 43 middle = len(arr) // 2 44 left, right = arr[:middle], arr[middle:] 45 return merge(merge_sort(left), merge_sort(right)) 46 47 48 def merge(left, right): 49 result = [] 50 while left and right: # 迴歸階段:將左右子節點合併到父節點 51 if left[0] <= right[0]: 52 result.append(left.pop(0)) 53 else: 54 result.append(right.pop(0)) 55 while left: 56 result.append(left.pop(0)) 57 while right: 58 result.append(right.pop(0)) 59 return result 60 61 62 def quick_sort(arr): 63 """ 64 5.快速排序:選定第一個元素爲基準,將後面的元素「依次」與基準比較, 65 較大的放基準右邊區域,較小的放基準左邊區域。 66 遞歸的對左右區域進行分區操做,直至該區域中只有一個元素了 67 """ 68 sort(arr, 0, len(arr) - 1) 69 70 71 def sort(arr, left, right): 72 if left >= right: # 遞歸終止條件:被分區區域內只有1個元素了 73 return 74 pivot = partition(arr, left, right) 75 # 遞歸的進行分區 76 sort(arr, left, pivot - 1) 77 sort(arr, pivot + 1, right) 78 79 80 # 分區,返回基準值的索引 81 def partition(arr, left, right): 82 pivotkey = arr[left] # 選定第一個元素爲基準值 83 while left < right: 84 while arr[right] >= pivotkey and right > left: 85 right -= 1 86 arr[left] = arr[right] # 小於基準值的元素放到左邊區域:小的往前甩 87 while arr[left] < pivotkey and left < right: 88 left += 1 89 arr[right] = arr[left] # 大於等於基準值的元素放到右邊區域:大的日後甩 90 arr[left] = pivotkey 91 return left 92 93 94 arr = [9, 8, 7, 6, 5, 4, 3, 2, 1] 95 # selection_sort(arr) 96 # buble_sort(arr) 97 # insert_sort(arr) 98 # print(merge_sort(arr)) 99 quick_sort(arr) 100 print(arr)
9.二分法查找:search.py
1 def search(l,val): 2 low,high = 0,len(l) - 1 # 查找範圍的開始和結束索引位 3 # 循環查找,每次去除一半 4 while low <= high: 5 mid = (low + high) // 2 # 中間數索引 6 if l[mid] < val: 7 low = mid + 1 8 elif l[mid] > val: 9 high = mid - 1 10 else: 11 return mid 12 13 14 l = [1,2,3,4,5,6,7,8,9,10] 15 print("Key index:",search(l,666))