0.简介
对于二叉树的遍历,有四种方式:层序输出,前序输出,中序输出,后序输出。但不论利用何种输出方式对二叉树进行遍历,其前提为必须提前已知一颗树。那么什么叫做已知一颗树呢?
所谓已知一棵树的意思即为:已经用数据结构定义好的树,通过该树可以知道哪个节点是根;哪个节点是左儿子,右儿子;哪个节点是左儿子的左右儿子等等这样的信息。在本文中,我们把得到这个已知树的过程称之为创建一颗树。
1.四种遍历方式示意图
2.如何构建一颗已知二叉树
利用层序输入的策略构建二叉树相对比较方便。当然也可以通过其他手段构建二叉树,但相对会比较麻烦,该种策略是最容易理解的。后续的实例中会介绍另外一种构建策略。
"""
#定义好节点类
#默认节点为空,利用重写构造函数的策略,使得每次定义一个节点,
#对应节点都包含了元素,左右儿子。
"""
class Node(object):#新式类
def __init__(self,elem=-1,lchild=None,rchild=None):
self.elem = elem
self.lchild = lchild
self.rchild = rchild
"""
#定义树类
#每颗树的构造函数都会初始化一个根节点
#并且会利用层序的策略定义添加节点构建已知树函数
"""
class Tree(object):
def __init__(self, root=None):
self.root = root
self.MyQueue = []
#把一个节点添加到树中的策略(层序)
def add(self,elem):
#定义一个带有给定元素elem的节点
node = Node(elem)
if self.root.elem == -1:#如果树是空的
self.root = node #那么当前节点就是根节点
self.MyQueue.append(self.root)#并把当前根节点放入自己构造的队列中
#如果当前树为非空
else:
#把当前队列中的第一个节点取出来
treeNode = self.MyQueue[0]
#如果取出的节点没有左子树,则把当前节点赋值给取出节点的左子树,
#并将该节点加入到自制对列中(因为后续还要给该节点添加左右子树)
if treeNode.lchild == None:
treeNode.lchild = node
self.MyQueue.append(treeNode.lchild)
#如果取出的节点已经有左子树了,那就把当前节点赋值给其右子树
#并将该节点加入到自制对列中(因为后续还要给该节点添加左右子树)
#而和左子树插入不同,右子树插入后,当前被取出节点就被填满了(因为是二叉树),
#所以该被取出节点需要从自制队列中弹出(注意这就是用对列不用栈的原因:先进先出)
else:
treeNode.rchild = node
self.MyQueue.append(treeNode.rchild)
self.MyQueue.pop(0)
if __name__ == '__main__':
tree = Tree()
tree.add(A)
tree.add(B)
tree.add(C)
tree.add(D)
tree.add(E)
tree.add(F)
tree.add(G)
3.根据已知二叉树遍历输出
层序输出:利用队列进行层序输出
def level(self):
if self.root == None:
return
MyQueue = []
node =self.root
MyQueue.append(node)
while MyQueue:
node = MyQueue.pop(0)
print node.elem
if node.lchild:
MyQueue.append(node.lchild)
if node.rchild:
MyQueue.append(node.rchild)
前序输出:根据父节点--左节点--右节点的顺序输出(利用递归)
中序输出:根据左节点--父节点--右节点的顺序输出(利用递归)
后序输出:根据左节点--右节点--父节点的顺序输出(利用递归)
def front(self):
if self.root == None:
return
print self.root.elem
self.front(self.root.lchild)
self.front(self.root.rchild)
def middle(self):
if self.root == None:
return
self.front(self.middle.lchild)
print self.root.elem
self.front(self.middle.rchild)
def post(self):
if self.root == None:
return
self.front(self.middle.lchild)
self.front(self.middle.rchild)
print self.root.elem
4.创建二叉树并遍历输出实例
比如我们在笔试的过程中会遇到的题目:已知一颗树的前序遍历和中序遍历,输出二叉树的层序遍历。该类题目的策略就是通过树的前序遍历和中序遍历来创建一颗已知树,并通过创建得到的树进行层序的遍历输出。
解题思路:利用递归的手段通过前序和中序的结果来构建已知树。并利用广度优先的手段遍历输出(就是层序遍历)。之所以可以利用递归,因为当根据前序遍历结果可知,第一位是整颗树的根节点,而根据中序遍历中找到当前这个第一位的index,在中序遍历序列中该index之前和之后的两段被切分成了两颗子树,并且根据这两颗子树的长度可以从前序的列表中切除这两颗子树的前序遍历列表,因此我们发现对于每一个节点的操作一致,且最终的终止条件为最原始的前序为空时递归结束。
import sys
class Node:
def __init__(self, val):
self.val = val
self.left, self.right = None, None
def buildTree(preTree, inTree):
if preTree:
root = Node(preTree[0])
index = inTree.index(preTree[0])
root.left = buildTree(preTree[1:index + 1], inTree[:index])
root.right = buildTree(preTree[index + 1:], inTree[index + 1:])
return root
else:
return None
n = int(sys.stdin.readline())
preTree = sys.stdin.readline().split()
inTree = sys.stdin.readline().split()
root = buildTree(preTree, inTree)
queue = [root]
nextqueue = []
try:
while queue:
for Node in queue:
print Node.val
if Node.left:
nextqueue.append(Node.left)
if Node.right:
nextqueue.append(Node.right)
queue, nextqueue = nextqueue, []
except:
pass
给自己打个小广告
本人211硕士毕业生,目前从事深度学习,机器学习计算机视觉算法行业,目前正在将我的各类学习笔记发布在我的公众号中,希望感兴趣一起学习的同学们可以关注下~~~
本人微信公众号:yuanCruise
网友评论