版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/myq151/article/details/83998846
二叉树的遍历是树的一种重要的运算。所谓遍历是指对树中所有结点的信息的访问,即依次对树中每个结点访问一次且仅访问一次,我们把这种对所有节点的访问称为遍历(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)