1. 程式人生 > >python編寫二叉樹演算法

python編寫二叉樹演算法

       二叉樹的遍歷是樹的一種重要的運算。所謂遍歷是指對樹中所有結點的資訊的訪問,即依次對樹中每個結點訪問一次且僅訪問一次,我們把這種對所有節點的訪問稱為遍歷(traversal)。那麼樹的兩種重要的遍歷模式是深度優先遍歷和廣度優先遍歷,深度優先一般用遞迴,廣度優先一般用佇列。以下使用深度優先和廣度優先遍歷二叉樹演算法。

廣度優先遍歷:


class Node(object):
    """二叉樹的節點型別"""

    def __init__(self, item):
        self.item =
item # 儲存節點的真是值 self.lchild = None # 指向左子樹的指標 self.rchild = None # 指向➡右子樹的指標 class BinaryTree(object): """二叉樹""" def __init__(self, node=None): self.root = node def add(self, item): """為樹新增節點(廣度優先遍歷的思想)""" if self.root is None: self.
root = Node(item) # 空樹 else: queue = [] # 初始化佇列 queue.append(self.root) # 將根節點入佇列 while len(queue) > 0: node = queue.pop(0) # 彈出節點 # 彈出判斷節點是否有左右子樹 if not node.lchild: # 沒有左子樹,將新節點新增上去即可
node.lchild = Node(item) # 注意:樹每次只新增一個節點,新增完畢退出迴圈 return else: # 有左子樹,繼續將左子樹新增到佇列中 queue.append(node.lchild) if not node.rchild: # 沒有右子樹,將新節點新增上去即可 node.rchild = Node(item) return else: # 有右子樹,繼續將右子樹新增到佇列中 queue.append(node.rchild) def breath_travel(self): """廣度優先遍歷""" if self.root is Node: return queue = [] # 樹不為空,初始化佇列 queue.append(self.root) while len(queue) > 0: node = queue.pop(0) # 彈出元素 print(node.item, end=" ") # 判斷是否有左右子樹 if node.lchild: # 左子樹有值新增到佇列繼續遍歷 queue.append(node.lchild) if node.rchild: # 右子樹有值新增到佇列繼續遍歷 queue.append(node.rchild) if __name__ == '__main__': tree = BinaryTree() for i in range(10): tree.add(i) tree.breath_travel() print(" ") 輸出:0 1 2 3 4 5 6 7 8 9

深度優先遍歷:


class Node(object):
    """二叉樹的節點型別"""

    def __init__(self, item):
        self.item = item  # 儲存節點的真是值
        self.lchild = None  # 指向左子樹的指標
        self.rchild = None  # 指向➡右子樹的指標


class BinaryTree(object):
    """二叉樹"""

    def __init__(self, node=None):
        self.root = node

    def add(self, item):
        """為樹新增節點(廣度優先遍歷的思想)"""
        if self.root is None:
            self.root = Node(item)  # 空樹
        else:
            queue = []  # 初始化佇列
            queue.append(self.root)  # 將根節點入佇列
            while len(queue) > 0:
                node = queue.pop(0)  # 彈出節點
                # 彈出判斷節點是否有左右子樹
                if not node.lchild:
                    # 沒有左子樹,將新節點新增上去即可
                    node.lchild = Node(item)
                    # 注意:樹每次只新增一個節點,新增完畢退出迴圈
                    return
                else:
                    # 有左子樹,繼續將左子樹新增到佇列中
                    queue.append(node.lchild)

                if not node.rchild:
                    # 沒有右子樹,將新節點新增上去即可
                    node.rchild = Node(item)
                    return
                else:
                    # 有右子樹,繼續將右子樹新增到佇列中
                    queue.append(node.rchild)


    def preorder(self, root):
        """
        先序遍歷: 根節點 左子樹 右子樹
        :param root:
        結果:0 1 3 7 8 4 9 2 5 6
        """
        if root is None:
            return
        print(root.item, end=" ")  # 1.根節點 0 1 3 7 8 4 9 2 5 6
        self.preorder(root.lchild)  # 2.遞迴呼叫左子樹 1 3 7 9 5
        self.preorder(root.rchild)  # 3.遞迴呼叫右子樹 8 4 2 6

    def inorder(self, root):
        """
        中序遍歷:左子樹 根節點 右子樹
        :param root:
        結果:7 3 8 1 9 4 0 5 2 6
        """
        if root is None:
            return
        self.inorder(root.lchild)  # 1.遞迴呼叫左子樹
        print(root.item, end=" ")  # 2.根節點
        self.inorder(root.rchild)  # 3.遞迴呼叫右子樹

    def postorder(self, root):
        """
        後序遍歷:左子樹  右子樹 根
        :param root:
        結果:7 8 3 9 4 1 5 6 2 0
        """
        if root is None:
            return
        self.postorder(root.lchild)  # 1.遞迴呼叫左子樹
        self.postorder(root.rchild)  # 2.遞迴呼叫右子樹
        print(root.item, end=" ")  # 3.根節點


if __name__ == '__main__':
    tree = BinaryTree()
    for i in range(10):
        tree.add(i)
    tree.preorder(tree.root)
    print(" ")
    tree.inorder(tree.root)
    print(" ")
    tree.postorder(tree.root)