已知前序[0 1 3 7 8 4 9 2 5 6 ] (根,所有左子树,所有右子树) 中序[7 3 8 1 9 4 0 5 2 6 ] 确定后序结果
思路:前序第一个值为根节点,可将中序分为左子树[7 3 8 1 9 4]和右子树[5 2 6 ],
左子树前:[1 3 7 8 4 9 ],中序[7 3 8 1 9 4 ]
右子树前:[2 5 6 ],中序[5 2 6 ]
算法:1、通过先序遍历找到根结点A,再通过A在中序遍历的位置找出左子树,右子树
2、在A的左子树中,找左子树的根结点(在前序中找),转步骤1
3、在A的右子树中,找右子树的根结点(在前序中找),转步骤1
def combin_pro(self,prolist,inlist): if not prolist or not inlist: return root = Tree(prolist[0]) index = inlist.index(root.data) root.lchild = self.combin_pro(prolist[1:index+1],inlist[0:index]) root.rchild = self.combin_pro(prolist[index+1:],inlist[index+1:]) return root
已知 中序[7 3 8 1 9 4 0 5 2 6 ] ,后序 [7,8,3,9,4,1,5,6,2,0] (所有左子树,所有右子树,根节点) 确定前序结果
思路:后序中的字后一个是整个数的根,可将中序分为左子树[7 3 8 1 9 4]和右子树[5 2 6 ],
左子树前:[1 3 7 8 4 9 ],中序[7 3 8 1 9 4 ]
右子树前:[2 5 6 ],中序[5 2 6 ]
算法:同上
def combin_post(self,inlist,postlist): if not inlist or not postlist: return root = Tree(postlist[-1]) index = inlist.index(root.data) root.lchild = self.combin_post(inlist[0:index],postlist[0:index]) root.rchild = self.combin_post(inlist[index+1:],postlist[index:len(postlist)-1])
例题分析:
首先:H节点是根节点,其左子树为前:GEDB; 中EGBD ,右子树前:FCA; 中:FAC
左子树分析: G节点为根,左子树前:E;中:E(E是根节点) ,右子树前:DB 中:BD(说明根节点为D,B 为其左子树(通过中序看)
右子树分析:F为根节点,左子树为空,右子树的根为C,A为其左子树(通过中序看)
结果:
程序:
#定义二叉树类 class Tree(object): def __init__(self,data,lchild=None,rchild=None): self.data = data self.lchild = lchild self.rchild = rchild #定义树类 class solution(object): #深度优先遍历 根节点->(递归)左子树->(递归)右子树 #非递归 def non_preorder(self, root): """非递归实现先序遍历(根左右)""" if not root: return stack = [root] #进栈 while stack: node = stack.pop() print(node.data, end=' ') if node.rchild: #右孩子 存在压入栈 左在右前 左先栈即右在前进栈 stack.append(node.rchild) if node.lchild: #左孩子 存在压入栈 stack.append(node.lchild) # 深度优先遍历 后序遍历:左子树(递归)->右子树(递归)->根节点 #非递归 def non_postorder(self, root): stack = [] node= root preNode = None while node or len(stack)>0: while node: # 把当前节点的所有左侧子结点压入栈 stack.append(node) node = node.lchild if len(stack)>0: temp = stack.pop() # 左孩为空则一定执行输出,且记录 #或者访问过右孩 则执行 if temp.rchild==None or temp.rchild == preNode: print(temp.data, end=' ') preNode = temp #记录刚被访问过的节点 else: #当节点右不为空,则当前节点先入栈,先处理右孩 stack.append(temp) node = temp.rchild def combin_pro(self,prolist,inlist): if not prolist or not inlist: return root = Tree(prolist[0]) index = inlist.index(root.data) root.lchild = self.combin_pro(prolist[1:index+1],inlist[0:index]) root.rchild = self.combin_pro(prolist[index+1:],inlist[index+1:]) return root def combin_post(self,inlist,postlist): if not inlist or not postlist: return root = Tree(postlist[-1]) index = inlist.index(root.data) root.lchild = self.combin_post(inlist[0:index],postlist[0:index]) root.rchild = self.combin_post(inlist[index+1:],postlist[index:len(postlist)-1]) return root if __name__ == '__main__': pro = [0,1,3,7,8,4,9,2,5,6] mid = [7,3,8,1,9,4,0,5,2,6] post= [7,8,3,9,4,1,5,6,2,0] A = solution() remake1 = A.combin_pro(pro,mid) A.non_postorder(remake1) print() remake2 = A .combin_post(mid,post) A.non_preorder(remake2)