1. 程式人生 > >Python二叉樹遍歷

Python二叉樹遍歷

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

一、廣度優先遍歷(層次遍歷)

從樹的root開始,從上到下從從左到右遍歷整個樹的節點

二、深度優先遍歷

對於一顆二叉樹,深度優先搜尋(Depth First Search)是沿著樹的深度遍歷樹的節點,儘可能深的搜尋樹的分支。

那麼深度遍歷有重要的三種方法。這三種方式常被用於訪問樹的節點,它們之間的不同在於訪問每個節點的次序不同。這三種遍歷分別叫做先序遍歷(preorder),中序遍歷(inorder)和後序遍歷(postorder)。

1、先序遍歷 在先序遍歷中,我們先訪問根節點,然後遞迴使用先序遍歷訪問左子樹,再遞迴使用先序遍歷訪問右子樹 根節點->左子樹->右子樹

2、中序遍歷 在中序遍歷中,我們遞迴使用中序遍歷訪問左子樹,然後訪問根節點,最後再遞迴使用中序遍歷訪問右子樹 左子樹->根節點->右子樹

3、後序遍歷 在後序遍歷中,我們先遞迴使用後序遍歷訪問左子樹和右子樹,最後訪問根節點 左子樹->右子樹->根節點

'''
樹形結構
'''

class Node(object):
    '''節點類'''
    def __init__(self, elem, lChild = None, rChild = None):
        self.elem = elem
        self.lChild = lChild #左子樹
        self.rChild = rChild #又子樹

class Tree(object):
    '''二叉樹'''
    def __init__(self, node = None):
        self.root = node

    def add(self, item):
        '''新增子樹'''
        '''
            思路
            1、先找到要新增元素的節點
        '''
        node = Node(item)

        if self.root is None:
            self.root = node
            return

        li = [self.root]
        while li:
            cur_node = li.pop(0)

            if cur_node.lChild is not None:
                li.append(cur_node.lChild)
            else:
                cur_node.lChild = node
                return

            if cur_node.rChild is not None:
                li.append(cur_node.rChild)
            else:
                cur_node.rChild = node
                return

    def breadth_travel(self):
        '''廣度優先遍歷'''
        if self.root is None:
            return

        li = [self.root]

        while li:
            cur_node = li.pop(0)
            print(cur_node.elem, end=' ')

            if cur_node.lChild is not None:
                li.append(cur_node.lChild)

            if cur_node.rChild is not None:
                li.append(cur_node.rChild)
        print(' ')



    def preorder(self, node):
        '''先序遍歷'''
        if node is None:
            return

        print(node.elem, end=' ')
        self.preorder(node.lChild)
        self.preorder(node.rChild)

    def inorder(self, node):
        '''中序優先遍歷'''
        if node is None:
            return

        self.preorder(node.lChild)
        print(node.elem, end=' ')
        self.preorder(node.rChild)

    def postorder(self, node):
        '''後續優先遍歷'''
        if node is None:
            return

        self.preorder(node.lChild)
        self.preorder(node.rChild)
        print(node.elem, end=' ')


if __name__ == "__main__":
    tree = Tree()
    tree.add(0)
    tree.add(1)
    tree.add(2)
    tree.add(3)
    tree.add(4)
    tree.add(5)
    tree.add(6)
    tree.add(7)
    tree.add(8)
    tree.add(9)
    tree.breadth_travel()
    print(" - ")
    tree.preorder(tree.root)
    print(" ")
    tree.inorder(tree.root)
    print(" ")
    tree.postorder(tree.root)
    print(" ")