python-二叉树-先根-中根-后根-递归-非递归-实现方法
=====================================================================
二叉树之先根/中根/后根遍历:
# 感谢兄弟连姚老师(python-爬虫)
又叫先序后序中序遍历;三种都是从上到下从左到右依次近栈,唯一不同的就是出栈顺序:
先序(根)遍历(Python3中新式类的继承顺序,MRO,C3算法):
输出顺序: 根-左(上)-右(上)
出栈顺序:近栈后立马出栈(出栈顺序就是输出顺序)
中序(根)遍历(可看做是x轴投影的排序,y轴无重叠)():
输出顺序: 左(下)-根-右(下)
出栈顺序:游标左下方无分支立马出栈
后续(根)遍历(左右子树先输出再输出根节点.)(从左到右,从下到上;最好记忆的):
输出顺序:左(下)-右(下)-根
出栈顺序:游标右下方无分支立马出栈
--------
递归代码:
# 二叉树的先根,中根,后根遍历
# 建议使用递归的方法来实现树的遍历,其他实现不专业
class TreeNode(object):
#python3新式类中object写不写都默认使用新式类的继承方式,都是继承object类
def __init__(self,num):
self.val = num
# 类能够动态绑定属性,但是只可以使用类绑定,不能通过实例化对象
# 绑定属性,因此可以在类里面写下面两行或者在后面写TreeNode.left=None;TreeNode.right=None;后才
# 能够进行t1.left = t2的属性赋值操作
# self.left=None
# self.right=None
# 递归都可以看作是进栈出栈
# 先根遍历
def preRecursion(root):
'''
pre:previous
Recursion:递归
root:二叉树的根
:param root:
:return:
'''
if root == None:
return None
# 入栈就打印
print(root.val,end='')
preRecursion(root.left)
preRecursion(root.right)
# 中根遍历
def midRecursion(root):
if root == None:
return None
# 出左栈打印
midRecursion(root.left)
print(root.val,end='')
midRecursion(root.right)
# 后根遍历
def afterRecursion(root):
if root == None:
return None
# 出右栈打印
afterRecursion(root.left)
afterRecursion(root.right)
print(root.val,end='')
if __name__ == '__main__':
t1 = TreeNode(1)
t2 = TreeNode(2)
t3 = TreeNode(3)
t4 = TreeNode(4)
t5 = TreeNode(5)
t6 = TreeNode(6)
t7 = TreeNode(7)
t8 = TreeNode(8)
TreeNode.left = None
TreeNode.right = None
t1.left = t2
t1.right = t3
t2.left = t4
t2.right = t5
t3.left = t6
t3.right = t7
t6.right = t8
'''
形如:
1
2 3
4 5 6 7
8
'''
# 先根遍历
preRecursion(t1)
print()
# 中根遍历
midRecursion(t1)
print()
# 后根遍历
afterRecursion(t1)
'''
结果:
12453687
42516837
45286731
'''
非递归写法:
# 二叉树的先根,中根,后根遍历
# 建议使用递归的方法来实现树的遍历,其他实现不专业
class TreeNode(object):
#python3新式类中object写不写都默认使用新式类的继承方式,都是继承object类
def __init__(self,num):
self.val = num
# 类能够动态绑定属性,但是只可以使用类绑定,不能通过实例化对象
# 绑定属性,因此可以在类里面写下面两行或者在后面写TreeNode.left=None;TreeNode.right=None;后才
# 能够进行t1.left = t2的属性赋值操作
self.left=None
self.right=None
# 递归本质上可以看出入栈和出栈的操作
def preOrder(root):
'''
:param root: 根
:return:
'''
if root == None:
return None
# 使用列表表示栈
stack = []
tmpNode = root
# 循环的头tmpNode/注意两个包含关系的while嵌套的重要性/while确定跳出条件,临界参数/
while tmpNode or stack:
while tmpNode:
print(tmpNode.val,end='')
# 入栈
stack.append(tmpNode)
tmpNode = tmpNode.left
node = stack.pop()
tmpNode = node.right
# 中根排序
def midOrder(root):
if root == None:
return None
stack = []
tmpNode = root
while tmpNode or stack:
while tmpNode:
stack.append(tmpNode)
tmpNode = tmpNode.left
node = stack.pop()
print(node.val,end='')
tmpNode = node.right
# 后根排序
def aftOrder(root):
if root == None:
return None
stack = []
tmpNode = root
while tmpNode or stack:
while tmpNode:
stack.append(tmpNode)
tmpNode = tmpNode.left
node = stack[-1]
tmpNode = node.right
if node.right == None:
print(node.val,end='')
node = stack.pop()
while stack and node == stack[-1].right:
node = stack.pop()
print(node.val,end='')
if __name__ == '__main__':
t1 = TreeNode(1)
t2 = TreeNode(2)
t3 = TreeNode(3)
t4 = TreeNode(4)
t5 = TreeNode(5)
t6 = TreeNode(6)
t7 = TreeNode(7)
t8 = TreeNode(8)
t1.left = t2
t1.right = t3
t2.left = t4
t2.right = t5
t3.left = t6
t3.right = t7
t6.right = t8
preOrder(t1);print()
midOrder(t1);print()
aftOrder(t1)