1. 程式人生 > 實用技巧 >資料結構與演算法-二叉樹和排序二叉樹

資料結構與演算法-二叉樹和排序二叉樹

二叉樹

  • 根節點
    • 柱狀結構最上層的一個節點
  • 葉子節點
    • 左葉子節點
    • 右葉子節點
  • 完整的子樹
    • 是由根節點,左右葉子節點組成
  • 非完整的子樹
    • 根節點,左葉子節點
    • 根節點,右葉子節點
    • 根節點
  • 特性:二叉樹中的任意一個節點都可以被視為另一顆子樹的根節點
    • 如果我們想要區分不同的子樹,使用根節點作為區分的標準
# 建立節點類
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