資料結構與演算法-二叉樹和排序二叉樹
阿新 • • 發佈:2020-08-08
二叉樹
- 根節點
- 柱狀結構最上層的一個節點
- 葉子節點
- 左葉子節點
- 右葉子節點
- 完整的子樹
- 是由根節點,左右葉子節點組成
- 非完整的子樹
- 根節點,左葉子節點
- 根節點,右葉子節點
- 根節點
- 特性:二叉樹中的任意一個節點都可以被視為另一顆子樹的根節點
- 如果我們想要區分不同的子樹,使用根節點作為區分的標準。
# 建立節點類 class Node(): def __init__(self,item): self.item = item self.left = None self.right = None# 建立一棵樹 class Tree(): def __init__(self): # 構建一顆空樹 self.root = None # 鏈頭,指向最上邊的根節點 def addNode(self, item): node = Node(item) # 如果self.root指向為,則是一顆空樹 if self.root == None: self.root = node return # 樹為非空 cur = self.root q= [cur] while True: pop_node = q.pop(0) # 將第一個節點取出 if pop_node.left == None: # 判斷這個節點左邊是不是為空 pop_node.left = node # 如果為空就將資料新增進去 break # 新增進去資料就結束迴圈 else: q.append(pop_node.left) # 如果不為空,就把它加到列表當中if pop_node.right == None: # 判斷這個節點右邊是不是為空 pop_node.right = node # 如果為空就將資料新增進去 break # 新增進去資料就結束迴圈 else: q.append(pop_node.right) # 如果不為空,就把它加到列表當中 # 廣度遍歷,遍歷整棵樹 def travel(self): cur = self.root q = [cur] while q: pop_node = q.pop(0) print(pop_node.item) if pop_node.left != None: q.append(pop_node.left) if pop_node.right != None: q.append(pop_node.right) tree = Tree() l = [1,2,3,4,5,6] for i in l: tree.addNode(i) tree.travel() 1 2 3 4 5 6
二叉樹的遍歷
- 廣度遍歷
- 自上而下逐層遍歷節點
- 深度遍歷:基於子樹遍歷。可以將前中後序遍歷以此作用在不同的子樹中即可。每一顆子樹中都會有一個根節點。
- 豎向遍歷的方式
- 方式:以此作用在每一個子樹
- 前序:根左右
- 中序:左根右
- 後序:左右根
class Node(): def __init__(self, item): self.item = item self.right = None self.left = None class Tree(): def __init__(self): self.root = None def addNode(self, item): node = Node(item) if self.root == None: self.root = node return cur = self.root q = [cur] while True: pop_node = q.pop(0) if pop_node.left != None: q.append(pop_node.left) else: pop_node.left = node break if pop_node.right != None: q.append(pop_node.right) else: pop_node.right = node break # 深度遍歷:前序遍歷:根左右 def forward(self, root): # root表示不同子樹的根節點 # 結束遞迴的條件 if root == None: # 結束標誌,如果根節點為空就結束遞迴 return print(root.item) # 根 self.forward(root.left) # 左 運用遞迴 self.forward(root.right) # 右 # 深度遍歷:中序遍歷:左根右 def middle(self,root): if root == None: return self.middle(root.left) # 左 print(root.item) # 根 self.middle(root.right) # 右 # 深度遍歷:後序遍歷:左右根 def back(self, root): if root == None: return self.back(root.left) # 左 self.back(root.right) # 右 print(root.item) # 根 tree = Tree() l = [1,2,3,4,5,6] for i in l: tree.addNode(i) tree.forward(tree.root) # 1,2,4,5,3,6 tree.middle(tree.root) # 4,2,5,1,6,3 tree.back(tree.root) # 4,5,2,6,3,1
排序二叉樹
- 排序二叉樹和上述普通二叉樹對應的插入節點的方式是截然不同。正是由於排序二叉樹獨有的插入節點的方式,才可以實現基於二叉樹進行排序。
- 插入方式:從根部開始比節點大往右插,比節點小往左插 (使用深度遍歷中的中序遍歷可以實現對資料的排序)
class Node(): def __init__(self, item): self.item = item self.right = None self.left = None class SortTree(): def __init__(self): self.root = None def add(self, item): node = Node(item) if self.root == None: self.root = node return cur = self.root while True: if item < cur.item: # 如果插入節點的值小於根節點,向左側插入 if cur.left == None: cur.left = node break else:# 插入的左側不為空 cur = cur.left else: # 向右側插入 if cur.right == None: cur.right = node break else: # 插入右側不為空 cur = cur.right def middle(self, root): if root == None: return self.middle(root.left) print(root.item) self.middle(root.right) tree = SortTree() l = [8,9,3,7,2,6,4] for i in l: tree.add(i) tree.middle(tree.root) 2 3 4 6 7 8 9