python編寫二叉樹演算法
阿新 • • 發佈:2018-11-13
二叉樹的遍歷是樹的一種重要的運算。所謂遍歷是指對樹中所有結點的資訊的訪問,即依次對樹中每個結點訪問一次且僅訪問一次,我們把這種對所有節點的訪問稱為遍歷(traversal)。那麼樹的兩種重要的遍歷模式是深度優先遍歷和廣度優先遍歷,深度優先一般用遞迴,廣度優先一般用佇列。以下使用深度優先和廣度優先遍歷二叉樹演算法。
廣度優先遍歷:
class Node(object):
"""二叉樹的節點型別"""
def __init__(self, item):
self.item = item # 儲存節點的真是值
self.lchild = None # 指向左子樹的指標
self.rchild = None # 指向➡右子樹的指標
class BinaryTree(object):
"""二叉樹"""
def __init__(self, node=None):
self.root = node
def add(self, item):
"""為樹新增節點(廣度優先遍歷的思想)"""
if self.root is None:
self. root = Node(item) # 空樹
else:
queue = [] # 初始化佇列
queue.append(self.root) # 將根節點入佇列
while len(queue) > 0:
node = queue.pop(0) # 彈出節點
# 彈出判斷節點是否有左右子樹
if not node.lchild:
# 沒有左子樹,將新節點新增上去即可
node.lchild = Node(item)
# 注意:樹每次只新增一個節點,新增完畢退出迴圈
return
else:
# 有左子樹,繼續將左子樹新增到佇列中
queue.append(node.lchild)
if not node.rchild:
# 沒有右子樹,將新節點新增上去即可
node.rchild = Node(item)
return
else:
# 有右子樹,繼續將右子樹新增到佇列中
queue.append(node.rchild)
def breath_travel(self):
"""廣度優先遍歷"""
if self.root is Node:
return
queue = [] # 樹不為空,初始化佇列
queue.append(self.root)
while len(queue) > 0:
node = queue.pop(0) # 彈出元素
print(node.item, end=" ")
# 判斷是否有左右子樹
if node.lchild:
# 左子樹有值新增到佇列繼續遍歷
queue.append(node.lchild)
if node.rchild:
# 右子樹有值新增到佇列繼續遍歷
queue.append(node.rchild)
if __name__ == '__main__':
tree = BinaryTree()
for i in range(10):
tree.add(i)
tree.breath_travel()
print(" ")
輸出:0 1 2 3 4 5 6 7 8 9
深度優先遍歷:
class Node(object):
"""二叉樹的節點型別"""
def __init__(self, item):
self.item = item # 儲存節點的真是值
self.lchild = None # 指向左子樹的指標
self.rchild = None # 指向➡右子樹的指標
class BinaryTree(object):
"""二叉樹"""
def __init__(self, node=None):
self.root = node
def add(self, item):
"""為樹新增節點(廣度優先遍歷的思想)"""
if self.root is None:
self.root = Node(item) # 空樹
else:
queue = [] # 初始化佇列
queue.append(self.root) # 將根節點入佇列
while len(queue) > 0:
node = queue.pop(0) # 彈出節點
# 彈出判斷節點是否有左右子樹
if not node.lchild:
# 沒有左子樹,將新節點新增上去即可
node.lchild = Node(item)
# 注意:樹每次只新增一個節點,新增完畢退出迴圈
return
else:
# 有左子樹,繼續將左子樹新增到佇列中
queue.append(node.lchild)
if not node.rchild:
# 沒有右子樹,將新節點新增上去即可
node.rchild = Node(item)
return
else:
# 有右子樹,繼續將右子樹新增到佇列中
queue.append(node.rchild)
def preorder(self, root):
"""
先序遍歷: 根節點 左子樹 右子樹
:param root:
結果:0 1 3 7 8 4 9 2 5 6
"""
if root is None:
return
print(root.item, end=" ") # 1.根節點 0 1 3 7 8 4 9 2 5 6
self.preorder(root.lchild) # 2.遞迴呼叫左子樹 1 3 7 9 5
self.preorder(root.rchild) # 3.遞迴呼叫右子樹 8 4 2 6
def inorder(self, root):
"""
中序遍歷:左子樹 根節點 右子樹
:param root:
結果:7 3 8 1 9 4 0 5 2 6
"""
if root is None:
return
self.inorder(root.lchild) # 1.遞迴呼叫左子樹
print(root.item, end=" ") # 2.根節點
self.inorder(root.rchild) # 3.遞迴呼叫右子樹
def postorder(self, root):
"""
後序遍歷:左子樹 右子樹 根
:param root:
結果:7 8 3 9 4 1 5 6 2 0
"""
if root is None:
return
self.postorder(root.lchild) # 1.遞迴呼叫左子樹
self.postorder(root.rchild) # 2.遞迴呼叫右子樹
print(root.item, end=" ") # 3.根節點
if __name__ == '__main__':
tree = BinaryTree()
for i in range(10):
tree.add(i)
tree.preorder(tree.root)
print(" ")
tree.inorder(tree.root)
print(" ")
tree.postorder(tree.root)