-
在学校刚刚学到的二叉树是用C语言来实现的,还涉及到了指针等操作。最近疫情原因不能开学,就自己学习了一下Python,就拿Python来试着实现一下,顺便再复习一下二叉树的一些知识。
-
本文使用Python来构建一个完全二叉树,并且实现树结点添加,层次遍历,先序遍历,中序遍历,后序遍历。
-
由于我自己对二叉树的理解也不是很深,所以关于二叉树的理论知识就只能自行脑补了,这里直接开始实现了,在实现的过程中也可能会有一些错误,还请大佬们批评指正。
-
以下为实现的思路,完整代码以及输出可以直接滑倒最后查看。
-
创建结点
-
首先创建一个结点的类,结点含有数据和左子,右子,创建后就直接将左子,右子初始化为None,数据则从外部输入进去。
# 创建一个结点的class
class Node(object):
def __init__(self,valua):
self.valua = valua
self.Lchild = None
self.Rchild = None
- 然后创建一个二叉树的类,因为结点已经创建了一个node的类,这里只需要初始化一个根结点为None就可以了。
# 创建一个二叉树class
class Btree(object):
def __init__(self):
# 初始化根结点
self.root = None
-
添加结点
-
接下来就可以来实现添加结点的funtion类。
-
实现思路主要是使用层次遍历来查找空的位置,先检查根节点是否为空,如果为空就直接把添加的结点赋值给根节点。
-
如果结点的左子为空就将结点添加到左子的位置,然后再检查右子。
-
这里使用了队列来进行查找,首先把根节点放在队列中。然后弹出第一个元素来判断左子右子是否为空,如果为空就直接赋值返回,如果不为空就把当前的结点添加到队列末尾,一直查找下去其实也相当于对树进行了层次的遍历,找到符合的位置后把该结点添加进去然即可。
def add_node(self,valua):
node = Node(valua)
# 如果根结点为空,则赋值给根结点
if self.root is None:
self.root = node
return
# 初始化队列,用于遍历
queue = [self.root]
while queue:
# 弹出第一个结点,先判断左子,后判断右子
# 如果为空,则赋值,否加入队列,为了下一次遍历使用
pop_node = queue.pop(0)
if pop_node.Lchild is None:
# print("add in Lchild",node.valua)
pop_node.Lchild = node
return
else:
queue.append(pop_node.Lchild)
if pop_node.Rchild is None:
pop_node.Rchild = node
return
else:
queue.append(pop_node.Rchild)
- 这里比较难理解的可能是队列的使用,这里使用了pop操作,取出后就把队列的第一个元素给删除了。已经删除的就说明已经查找过来,如果队列还有元素就说明还没有查找到最后一个,完全二叉树也就还没有遍历结束。
- 添加到队列中的元素实际上也是按照层次遍历的顺序进行添加到,这样查找就能从根节点按照层次一直查找到最后一个结点,最终完成添加过程。
- 层次遍历
- 接下来是对二叉树的层次遍历,层次遍历和增加结点类似,也是使用队列来进行,如果左子或者右子不为空就继续输出下去就行了 。
# 层次遍历
def level_order(self):
# 使用队列进行,拿出第一个元素输出
# 先判断左子,后判断右子,如果不为空则加到队列中,继续遍历
# 判断根节点,如果为空则为空树
if self.root is None:
return
print(self.root.valua,end=' ')
queue = [self.root]
while queue:
node = queue.pop(0)
if node.Lchild is not None:
print(node.Lchild.valua,end=' ')
queue.append(node.Lchild)
if node.Rchild is not None:
print(node.Rchild.valua,end=' ')
queue.append(node.Rchild)
- 先序遍历
- 先序遍历的顺序为:根 左 右
- 这里使用递归来实现,先输出根节点的值,然后递归查找左子,再递归查找右子。
- 递归的终止条件为当前遍历的结点为空。
def pre_order(self,node):
# 先序遍历 先打印根节点的数据,递归下去
# 结点为空时结束递归
if node is None:
return
print(node.valua,end=' ')
self.pre_order(node.Lchild)
self.pre_order(node.Rchild)
- 中序遍历
- 中序遍历的顺序为:左 根 右
- 中序遍历与先序遍历的思路一样,只是先输出左子的值,在代码实现上仅仅是把输出函数改了下位置而已。
def in_order(self,node):
# 中序遍历
if node is None:
return
self.in_order(node.Lchild)
print(node.valua,end=' ')
- 后序遍历
- 后序遍历的顺序为:左 右 根
- 实现思路和前面的先序和中序相同,改变了一下先输出的值。
def post_order(self,node):
# 后序遍历
if node is None:
return
self.post_order(node.Lchild)
self.post_order(node.Rchild)
print(node.valua,end=' ')
完整代码
# 创建一个结点的class
class Node(object):
def __init__(self,valua):
self.valua = valua
self.Lchild = None
self.Rchild = None
# 创建一个二叉树class
class Btree(object):
def __init__(self):
# 初始化根结点
self.root = None
# 增加结点(广度搜索)
def add_node(self,valua):
node = Node(valua)
# 如果根结点为空,则赋值给根结点
if self.root is None:
self.root = node
return
# 初始化队列,用于遍历
queue = [self.root]
while queue:
# 弹出第一个结点,先判断左子,后判断右子
# 如果为空,则赋值,否加入队列,为了下一次遍历使用
pop_node = queue.pop(0)
if pop_node.Lchild is None:
# print("add in Lchild",node.valua)
pop_node.Lchild = node
return
else:
queue.append(pop_node.Lchild)
if pop_node.Rchild is None:
pop_node.Rchild = node
return
else:
queue.append(pop_node.Rchild)
# 层次遍历
def level_order(self):
# 使用队列进行,拿出第一个元素遍历
# 先判断左子,后判断右子,如果不为空则加到队列中,继续遍历
# 判断根节点,如果为空则为空树
if self.root is None:
return
print(self.root.valua,end=' ')
queue = [self.root]
while queue:
node = queue.pop(0)
if node.Lchild is not None:
print(node.Lchild.valua,end=' ')
queue.append(node.Lchild)
if node.Rchild is not None:
print(node.Rchild.valua,end=' ')
queue.append(node.Rchild)
def pre_order(self,node):
# 先序遍历 先打印根节点的数据,递归下去
# 结点为空时结束递归
if node is None:
return
print(node.valua,end=' ')
self.pre_order(node.Lchild)
self.pre_order(node.Rchild)
def in_order(self,node):
# 中序遍历
if node is None:
return
self.in_order(node.Lchild)
print(node.valua,end=' ')
self.in_order(node.Rchild)
def post_order(self,node):
# 后序遍历
if node is None:
return
self.post_order(node.Lchild)
self.post_order(node.Rchild)
print(node.valua,end=' ')
#创建一个二叉树
a = Btree()
a.add_node(0)
a.add_node(1)
a.add_node(2)
a.add_node(3)
a.add_node(4)
a.add_node(5)
a.add_node(6)
a.add_node(7)
a.add_node(8)
a.add_node(9)
print('层次遍历:',end=' ')
a.level_order()
print('\n先序遍历:',end=' ')
a.pre_order(a.root)
print('\n中序遍历:',end=' ')
a.in_order(a.root)
print('\n后序遍历:',end=' ')
a.post_order(a.root)
- 输出结果
层次遍历: 0 1 2 3 4 5 6 7 8 9
先序遍历: 0 1 3 7 8 4 9 2 5 6
中序遍历: 7 3 8 1 9 4 0 5 2 6
后序遍历: 7 8 3 9 4 1 5 6 2 0
来源:CSDN
作者:qq_31801129
链接:https://blog.csdn.net/qq_31801129/article/details/104796145