二叉樹與遍歷的Python實現
阿新 • • 發佈:2019-02-02
二叉樹簡介
在電腦科學中,二叉樹(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的規則
由於本人水平有限,難免出現錯漏之處,歡迎批評指正