1. 程式人生 > >二叉樹與遍歷的Python實現

二叉樹與遍歷的Python實現

二叉樹簡介

在電腦科學中,二叉樹(Binary tree)是每個節點最多隻有兩個分支(不存在分支度大於2的節點)的樹結構。通常分支被稱作“左子樹”和“右子樹”。二叉樹的分支具有左右次序,不能顛倒。

具體實現

節點

class node(object):
    def __init__(self, val):
        self.val = val
        self.left = None
        self.right = None

二叉樹

class BinaryTree(object)
:
def __init__(self): #初始化連結串列為空表 self.root = None self.nodeLayer = dict() # 根據輸入的BFS的資料生成二叉樹 def initBinaryTree(self, *data): if data == None: raise ValueError('root node need one number') # 層數,從0開始 layerCount = 0 length = len(data) # 補為偶數
if length%2 != 0: list(data).append('#') length += 1 while self.power(2,layerCount) < length+1: self.nodeLayer[str(layerCount)] = list() start = self.power(2,layerCount)-1 stop = min(start*2+1,length) if layerCount == 0
: self.nodeLayer[str(layerCount)].append(node(data[0])) self.root = self.nodeLayer[str(layerCount)][0] else: nodeCount = 0 for p,q in zip(range(start,stop,2),range(start+1,stop,2)): self.nodeLayer[str(layerCount)].append(node(data[p])) self.nodeLayer[str(layerCount)].append(node(data[q])) # 上層節點 tmpNode = self.nodeLayer[str(layerCount-1)][nodeCount] tmpNode.left = self.nodeLayer[str(layerCount)][p-self.power(2,layerCount)+1] tmpNode.right = self.nodeLayer[str(layerCount)][q-self.power(2,layerCount)+1] nodeCount += 1 layerCount += 1 def power(self, x, n): s = 1 while n > 0: n = n - 1 s = s * x return s

根據輸入的列表建立二叉樹,輸入的資料和建立二叉樹的過程都按照廣度優先(BFS),比如

  1
 / \
2   3

對應的列表為[1,2,3]

為了區分下面的兩種情況:

  1
 /
2

1
 \
  2

分別寫作[1,2,'#'][1,'#',2]

    1
   / \
  2   3
 / \   \
4   5   6
   / \
  7   8

對於這個二叉樹,就可以序列化為[1,2,3,4,5,'#',6,'#','#',7,8],其中

1: the root
2: left child of 1
3: right child of 1
4: left child of 2
5: right child of 2
#: left child of 3
6: right child of 3
#: left child of 4
#: right child of 4
7: left child of 5
8: right child of 5

可以使用程式碼

tree = BinaryTree()
data = [1,2,3,4,5,'#',6,'#','#',7,8]
tree.initBinaryTree(*data)

得到上面的二叉樹

遍歷

深度優先演算法(DFS)

深度優先搜尋演算法(Depth-First-Search,簡稱DFS)是一種盲目搜尋演算法,用於遍歷或搜尋樹或圖。沿著樹的深度遍歷樹的節點,儘可能深的搜尋樹的分支。當節點v的所在邊都己被探尋過,搜尋將回溯到發現節點v的那條邊的起始節點。這一過程一直進行到已發現從源節點可達的所有節點為止。如果還存在未被發現的節點,則選擇其中一個作為源節點並重復以上過程,整個程序反覆進行直到所有節點都被訪問為止。

從圖中,可以直觀的看出搜尋的順序:


這裡寫圖片描述

先序、中序和後序遍歷都是深度優先搜尋演算法的特例
L、D、R分別表示遍歷左子樹、訪問根結點和遍歷右子樹,先序遍歷二叉樹的順序是DLR,中序遍歷二叉樹的順序是LDR,後序遍歷二叉樹的順序是LRD。

先序遍歷

DLR_list = []
def DLR(node):
    DLR_list.append(node.val)
    if node.left  != None:
        DLR(node.left)
    if node.right != None:
        DLR(node.right)
    return DLR_list

執行一下

print(DLR(tree.root))
[1, 2, 4, '#', '#', 5, 7, 8, 3, '#', 6]

中序遍歷

LDR_list = []
def LDR(node):
    if node.left  != None:
        LDR(node.left)
    LDR_list.append(node.val)
    if node.right != None:
        LDR(node.right)
    return LDR_list

執行一下

print(LDR(tree.root))
['#', 4, '#', 2, 7, 5, 8, 1, '#', 3, 6]

後序遍歷

LRD_list = []
def LRD(node):
    if node.left  != None:
        LRD(node.left)
    if node.right != None:
        LRD(node.right)
    LRD_list.append(node.val)
    return LRD_list

執行一下

print(LRD(tree.root))
['#', '#', 4, 7, 8, 5, 2, '#', 6, 3, 1]

廣度優先演算法(BFS)

廣度優先搜尋演算法(Breadth-First-Search,縮寫為BFS),又譯作寬度優先搜尋,或橫向優先搜尋,也是一種盲目搜尋演算法,用於遍歷或搜尋樹或圖。簡單的說,BFS是從根節點開始,沿著樹的寬度遍歷樹的節點,如果所有節點均被訪問,則演算法中止。


這裡寫圖片描述

在上面的二叉樹的初始化過程中就是遵循BFS的規則

由於本人水平有限,難免出現錯漏之處,歡迎批評指正