Python__數據結構與算法——樹、二叉樹(實現先、中、後序遍歷)

目錄

一、樹

二、二叉樹


樹和前面所講的表、堆棧和隊列等這些線性數據結構不同,樹不是線性的。在處理較多數據時,使用線性結構較慢,而使用樹結構則可以提高處理速度。不過,相對於線性的表、堆棧和隊列等線性數據結構來說,樹的構建便顯得複雜了。

一、樹

樹是一種非線性的數據結構,如圖-1 所示,之所以稱之爲樹,是因爲其形狀像一棵倒置的樹。每顆樹都有一個根節點,如圖-1 所示的樹中,Root 爲根節點。A、B、C 爲 Root 的兒子,Root 爲 A、B、C 的父親。A、B、C 爲兄弟。同樣,A 爲 D、E 的父親,D、E 爲 A 的兒子,D、E爲兄弟。D、E爲 Root 的孫子,Root 爲 D、E 的祖父。在樹中,如果一個元素沒有兒子,則稱之爲樹的葉子。

在 Python 中,樹的實現可以使用列表或者類的方式。使用列表的方式較爲簡便,但樹的構建過程較爲複雜。使用類的方式構建樹時,需要首先確定樹中的節點所能擁有的最大兒子數。因爲每個節點所擁有的兒子數量並不一定相同,因此使用類的方法將佔用更大的存儲空間。

如下所示的 pytree.py 腳本,以列表的形式構建了圖-1所示的樹。

# -*- coding:UTF-8 -*-
# file: pytree.py

G = ['G', []]  # 構造葉子 G,樹中每個元素都由該元素的值和該元素的兒子列表組成
H = ['H', []]  # 構造葉子 H
I = ['I', []]  # 構造葉子 I
K = ['K', []]  # 構造葉子 K
E = ['E', [G, H, I, K]]  # 構造 E 節點
D = ['D', []]  # 構造葉子 D
F = ['F', []]  # 構造葉子 F
A = ['A', [D, E]]  # 構造 A 節點
B = ['B', []]  # 構造葉子 B
C = ['C', [F]]  # 構造 C 節點
Root = ['Root', [A, B, C]]  # 構造樹根
print(Root)

輸出結果:

C:\Users\圖圖\AppData\Local\Programs\Python\Python37-32\python.exe D:/Python/pytree.py
['Root', 
[['A', [['D', []], ['E', [['G', []], ['H', []], ['I', []], ['K', []]]]]], 
['B', []], 
['C', [['F', []]]]
]]

Process finished with exit code 0

二、二叉樹

二叉樹是一類比較特殊的樹,在二叉樹中每個節點最多隻有兩個兒子,分爲左和右,如圖-2 所示。相對於樹而言,二叉樹的構建和使用都要簡單得多。

任何一棵樹,都可以通過變換轉換成一棵二叉樹。

在 Python 中,二叉樹的構建和樹一樣,可以使用列表或者類的方式。由於二叉樹中的節點具有確定的兒子數,因此,使用類的方式更爲簡便。下面所示的 pytree.py 用較爲簡單的方式生成了如圖-2所示的樹。

# -*- coding:UTF-8 -*-
# file: pytree.py


class Btree:  # 二叉樹節點
    def __init__(self, value):  # 初始化函數
        self.left = None  # 左兒子
        self.data = value  # 節點值
        self.right = None  # 右兒子

    def insertLeft(self, value):  # 向左子樹插入節點
        self.left = Btree(value)
        return self.left

    def insertRight(self, value):  # 向右子樹插入節點
        self.right = Btree(value)
        return self.right

    def show(self):  # 輸出節點數據
        print(self.data)


if __name__ == '__main__':
    Root = Btree('Root')  # 根節點
    A = Root.insertLeft('A')  # 向根節點中插入 A 節點
    C = A.insertLeft('C')  # 向 A 節點中插入 C 節點
    D = A.insertRight('D')  # 向 A 節點中插入 D 節點
    F = D.insertLeft('F')  # 向 D 節點中插入 F 節點
    G = D.insertRight('G')  # 向 D 節點中插入 G 節點
    B = Root.insertRight('B')  # 向根節點中插入 B 節點
    E = B.insertRight('E')  # 向 B 節點中插入 E 節點
    Root.show()  # 輸出節點數據
    Root.left.show()
    Root.right.show()
    A = Root.left
    A.left.show()
    Root.left.right.show()

輸出結果:

當創建好一棵二叉樹後,可以按照一定的順序對樹中所有的元素進行遍歷。按照先左後右,樹的遍歷方法有三種:先序遍歷、中序遍歷和後序遍歷。

先序遍歷的次序——如果二叉樹不爲空,則先訪問節點,然後訪問子樹,最後訪問子樹;否則,程序退出。

中序遍歷的次序——如果二叉樹不爲空,則先訪問子樹,然後訪問節點,最後訪問子樹;否則,程序退出。

後序遍歷的次序——如果二叉樹不爲空,則先訪問子樹,然後訪問節點,最後訪問子樹;否則,程序退出。

下面所示的 TreeTraversal.py 腳本使用了三種遍歷方式遍歷圖-2 所示的樹。

# -*- coding:UTF-8 -*-
# file: TreeTraversal.py


class BTree:  # 二叉樹節點
    def __init__(self, value):  # 初始化函數
        self.left = None  # 左兒子
        self.data = value  # 節點值
        self.right = None  # 右兒子

    def insertLeft(self, value):  # 向左子樹插入節點
        self.left = BTree(value)
        return self.left

    def insertRight(self, value):  # 向右子樹插入節點
        self.right = BTree(value)
        return self.right

    def show(self):  # 輸出節點數據
        print(self.data)


def preorder(node):  # 先序遍歷
    if node.data:
        node.show()
        if node.left:
            preorder(node.left)
        if node.right:
            preorder(node.right)


def inorder(node):  # 中序遍歷
    if node.data:
        if node.left:
            inorder(node.left)
        node.show()
        if node.right:
            inorder(node.right)


def postorder(node):  # 後序遍歷
    if node.data:
        if node.left:
            postorder(node.left)
        if node.right:
            postorder(node.right)
        node.show()


if __name__ == '__main__':
    Root = BTree('Root')  # 構建樹
    A = Root.insertLeft('A')
    C = A.insertLeft('C')
    D = A.insertRight('D')
    F = D.insertLeft('F')
    G = D.insertRight('G')
    B = Root.insertRight('B')
    E = B.insertRight('E')
    print('**************************')
    print('Binary Tree Pre-Traversal')
    print('**************************')
    preorder(Root)  # 對樹進行先序遍歷
    print('**************************')
    print('Binary Tree In-Traversal')
    print('**************************')
    inorder(Root)  # 對樹進行中序遍歷
    print('**************************')
    print('Binary Tree Post-Traversal')
    print('**************************')
    postorder(Root)  # 對樹進行後序遍歷

運行 TreeTraversal.py 腳本輸出結果:

C:\Users\圖圖\AppData\Local\Programs\Python\Python37-32\python.exe D:/Python/TreeTraversal.py
**************************
Binary Tree Pre-Traversal
**************************
Root
A
C
D
F
G
B
E
**************************
Binary Tree In-Traversal
**************************
C
A
F
D
G
Root
B
E
**************************
Binary Tree Post-Traversal
**************************
C
F
G
D
A
E
B
Root

Process finished with exit code 0
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章