數據結構及算法基礎學習筆記

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))
相關文章
相關標籤/搜索