Python实现二叉树的前后序遍历
二叉树的结构:
前中后序遍历对应的规则:
先序遍历
先序遍历的原则是:先根、再左、再右。
即:ABCDEFGH
中序遍历
中序遍历的原则是:先左、再根、再右。
即:BDCEAFHG
后序遍历
后序遍历的原则是:先左、再右、再根。
即:DECBHGFA
-
# 首先定义树的根节点
-
class Node(object):
-
"""docstring for Node"""
-
-
def __init__(self, elem=0, left=None, right=None):
-
self.elem = elem
-
self.lchild = left
-
self.rchild = right
-
-
-
# 定义一棵二叉树
-
class BinaryTree(object):
-
"""docstring for BinaryTree"""
-
-
def __init__(self):
-
# 根节点
-
self.root = None
-
-
def add(self, item):
-
# 向树中插入元素, 使用队列存储元素, 读取与弹出
-
node = Node(item)
-
if self.root is None:
-
self.root = node
-
return
-
# 用顺序表实现队列, 先入先出FIFO
-
# 首先传入根节点信息
-
queue = [self.root]
-
-
while queue:
-
cur_node = queue.pop(0)
-
-
# 若当前节点的左孩子为空, 将节点赋给当前节点左孩子
-
if cur_node.lchild is None:
-
cur_node.lchild = node
-
return
-
# 若当前节点左孩子不为空, 左孩子添加到当前节点中
-
else:
-
queue.append(cur_node.lchild)
-
-
# 接下来同样判断右孩子
-
if cur_node.rchild is None:
-
cur_node.rchild = node
-
return
-
else:
-
queue.append(cur_node.rchild)
-
-
def breadth_travel(self):
-
"""广度遍历: 方法同add, 是一种反过来的操作
-
"""
-
# 使用队列
-
queue = [self.root]
-
ret = []
-
if self.root is None:
-
return
-
while queue:
-
cur_node = queue.pop(0)
-
# 打印结点值
-
# print(cur_node.elem, end=" ")
-
ret.append(cur_node.elem)
-
if cur_node.lchild:
-
queue.append(cur_node.lchild)
-
if cur_node.rchild:
-
queue.append(cur_node.rchild)
-
print(ret)
-
-
def pre_order(self, node):
-
"""前序遍历: 递归方法"""
-
# if node is None:
-
# return
-
# print(node.elem, end=" ")
-
# self.pre_order(node.lchild)
-
# self.pre_order(node.rchild)
-
ret = []
-
-
def recur_0(node):
-
if node:
-
ret.append(node.elem)
-
recur_0(node.lchild)
-
recur_0(node.rchild)
-
recur_0(node)
-
print(ret)
-
-
def in_order(self, node):
-
"""中序遍历"""
-
# if node is None:
-
# return
-
# self.in_order(node.lchild)
-
# print(node.elem, end=" ")
-
# self.in_order(node.rchild)
-
ret = []
-
-
def recur_1(node):
-
if node:
-
recur_1(node.lchild)
-
ret.append(node.elem)
-
recur_1(node.rchild)
-
recur_1(node)
-
print(ret)
-
-
def post_order(self, node):
-
"""后序遍历"""
-
# 递归遍历跳出的条件
-
# if node is None:
-
# return
-
# self.pre_order(node.lchild)
-
# self.pre_order(node.rchild)
-
# print(node.elem, end=" ")
-
ret = []
-
-
def recur(node):
-
if node:
-
recur(node.lchild)
-
recur(node.rchild)
-
ret.append(node.elem)
-
recur(node)
-
print(ret)
-
-
def pre_order_1(self, node):
-
"""前序遍历(中左右): 非递归, 需要使用栈(递归的本质是栈实现)来实现"""
-
# 定义一个栈
-
st = []
-
# 定义顺序数组
-
result_arr = []
-
if node:
-
st.append(node)
-
while st:
-
node = st.pop()
-
# 中
-
result_arr.append(node.elem)
-
# 右
-
if node.rchild:
-
st.append(node.rchild)
-
# 左
-
if node.lchild:
-
st.append(node.lchild)
-
print(result_arr)
-
-
def in_order_1(self, node):
-
"""中序遍历(左中右), 需要指针(由于遍历的节点顺序和处理的节点顺序不同)"""
-
st = []
-
result_arr = []
-
cur_node = node
-
while cur_node or st:
-
if cur_node:
-
# 利用指针访问结点,访问到最底层数据
-
# 结点入栈
-
st.append(cur_node)
-
# 左
-
cur_node = cur_node.lchild
-
else:
-
cur_node = st.pop()
-
# 中
-
result_arr.append(cur_node.elem)
-
# 右
-
cur_node = cur_node.rchild
-
print(result_arr)
-
-
def in_order_2(self, node):
-
"""中序遍历(左中右), 通解"""
-
st = []
-
result_arr = []
-
if node:
-
st.append(node)
-
while st:
-
node = st[-1]
-
if node:
-
st.pop()
-
if node.rchild:
-
st.append(node.rchild)
-
st.append(node)
-
# 空节点入栈作为标记
-
st.append(None)
-
if node.lchild:
-
st.append(node.lchild)
-
else:
-
# 空节点出栈
-
st.pop()
-
node = st[-1]
-
st.pop()
-
result_arr.append(node.elem)
-
print(result_arr)
-
-
def post_order_1(self, node):
-
"""后序遍历(左右中), 可以直接由前序遍历得到"""
-
# 定义一个栈
-
st = []
-
# 定义顺序数组
-
result_arr = []
-
if node:
-
st.append(node)
-
while st:
-
node = st.pop()
-
# 中
-
result_arr.append(node.elem)
-
# 左
-
if node.lchild:
-
st.append(node.lchild)
-
# 右
-
if node.rchild:
-
st.append(node.rchild)
-
print(result_arr[::-1])
-
-
def post_order_2(self, node):
-
"""后序遍历(左右中), 可以直接由前序遍历得到"""
-
# 定义一个栈
-
st = []
-
# 定义顺序数组
-
result_arr = []
-
while st or node:
-
while node:
-
st.append(node)
-
# 遍历二叉树直到结点不再含有左节点(右节点)
-
node = node.lchild if node.lchild else node.rchild
-
node = st.pop()
-
# 最后加入中结点
-
result_arr.append(node.elem)
-
# 判断并开始遍历右节点(node指向右节点), 然后继续进行入栈操作(while内循环)
-
node = st[-1].rchild if st and st[-1].lchild == node else None
-
print(result_arr)
-
-
-
if __name__ == '__main__':
-
tree = BinaryTree()
-
for i in range(9):
-
tree.add(i)
-
print("广度遍历: ")
-
tree.breadth_travel()
-
print("\n深度遍历: ")
-
print("前序遍历: 递归")
-
tree.pre_order(tree.root)
-
print("中序遍历: 递归")
-
tree.in_order(tree.root)
-
print("后序遍历: 递归")
-
tree.post_order(tree.root)
-
print()
-
print("前序遍历: 非递归")
-
tree.pre_order_1(tree.root)
-
print("中序遍历: 非递归")
-
tree.in_order_1(tree.root)
-
print("中序遍历: 非递归, 不需要指针")
-
tree.in_order_2(tree.root)
-
print("后序遍历: 非递归, 修改自前序")
-
tree.post_order_1(tree.root)
-
print("后序遍历: 非递归, 直接写")
-
tree.post_order_2(tree.root)
-
-
"""
-
广度遍历:
-
0 1 2 3 4 5 6 7 8
-
深度遍历:
-
前序遍历: 递归
-
0 1 3 7 8 4 2 5 6
-
中序遍历: 递归
-
7 3 8 1 4 0 5 2 6
-
后序遍历: 递归
-
7 8 3 4 1 5 6 2 0
-
前序遍历: 非递归
-
[0, 1, 3, 7, 8, 4, 2, 5, 6]
-
中序遍历: 非递归
-
[7, 3, 8, 1, 4, 0, 5, 2, 6]
-
后序遍历: 非递归
-
[7, 8, 3, 4, 1, 5, 6, 2, 0]
-
"""
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgkicjg
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13