1. 程式人生 > >DFS遍歷以及反轉二叉樹Python實現

DFS遍歷以及反轉二叉樹Python實現

如果一個二叉樹,我們要按照深度優先方式遍歷它,需要做三件事情:遍歷左子樹、遍歷右子樹和訪問根節點。下面使用L、R、D表示這三項工作。
在這裡插入圖片描述
選擇這三項工作的不同順序,就可以得到三種常見遍歷順序:
1. 先根序遍歷(按照DLR順序)
2. 中根序遍歷(按照LDR順序)
3. 後根序遍歷(按照LRD順序)

二叉樹的list實現

二叉樹是遞迴結構,Python的list也是遞迴結構。基於list型別很容易實現二叉樹,例如,可以如下設計:
1. 空樹用None表示
2. 非空二叉樹用包含三個元素的表[d, l, r]表示,其中d 表示存在根節點的元素,l和r是兩棵子樹,採用與整個二叉樹同樣結構的list表示。
例如:


[‘A’, [‘B’, None, None],
[‘C’, [‘D’, [‘F’, None, None], [‘G’, None, None]],
[‘E’, [‘H’, None, None], [‘I’, None, None]]]]
下面就用Python程式碼實現:

class BinTreeList(object):
    def BinTree(self, data, left=None, right=None):
        return [data, left, right]
    
    def root(self, btree):
        return btree[0]

    def left(self, btree):
        return btree[1]

    def right(self, btree):
        return btree[2]

    def set_root(self, btree, data):  # 設定root結點
        btree[0] = data

    def set_left(self, btree, left):    # 設定左子樹
        btree[1] = left

    def set_right(self, btree, right):  # 設定右子樹
        btree[2] = right

    def preorder(self, btree):   # 先根序遍歷
        if btree is not None:
            print(self.root(btree))
            self.preorder(self.left(btree))
            self.preorder(self.right(btree))

    def midorder(self, btree):  # 中根序遍歷
        if btree is not None:
            self.midorder(self.left(btree))
            print(self.root(btree))
            self.midorder(self.right(btree))

    def posorder(self, btree):  # 後根序遍歷
        if btree is not None:
            self.posorder(self.left(btree))
            self.posorder(self.right(btree))
            print(self.root(btree))

    def reverse(self, btree):   # 反轉二叉樹
        if btree is not None:
            btree[1], btree[2] = btree[2], btree[1]
            self.reverse(self.left(btree))
            self.reverse(self.right(btree))

下面,我們進行測試:

if __name__ == "__main__":
    bintree = BinTreeList()
    t1 = bintree.BinTree("A", bintree.BinTree("B"),
                                bintree.BinTree("C",
                                bintree.BinTree("D", bintree.BinTree("F"), bintree.BinTree("G")),
                                bintree.BinTree("E", bintree.BinTree("H"), bintree.BinTree("I"))))
    print(t1)
    bintree.preorder(t1)
    bintree.midorder(t1)
    bintree.posorder(t1)
    print(bintree.root(t1))

[‘A’, [‘B’, None, None], [‘C’, [‘D’, [‘F’, None, None], [‘G’, None, None]], [‘E’, [‘H’, None, None], [‘I’, None, None]]]]
然後,可以分別測試先、中、後根序遍歷是否準確。
最後,我們可以反轉二叉樹,看看反轉之後的二叉樹是什麼樣的。

if __name__ == "__main__":
    bintree = BinTreeList()
    t1 = bintree.BinTree("A", bintree.BinTree("B"),
                                bintree.BinTree("C",
                                bintree.BinTree("D", bintree.BinTree("F"), bintree.BinTree("G")),
                                bintree.BinTree("E", bintree.BinTree("H"), bintree.BinTree("I"))))
    # bintree.set_left(bintree.left(t1), bintree.BinTree(5))
    print(t1)
    bintree.reverse(t1)
    bintree.preorder(t1)

[A,C,E,I,H,D,G,F,B]——這就是反轉之後的二叉樹先根遍歷結果,其實就是將左右子樹的結點相互調換。