博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python实现:给定二叉树的先序遍历和中序遍历结果,确定该二叉树的后序遍历结果
阅读量:3565 次
发布时间:2019-05-20

本文共 3070 字,大约阅读时间需要 10 分钟。

最近在学习二叉树,遇到了这样一题,在这里给大家提供一种方法,可能不是最好的,仅供大家参考和相互交流学习。    已知一个二叉树前序遍历、中序遍历的结果,请确定该二叉树并输出其后序遍历的结果。例如:        先序遍历结果为:A B D E G C F H;             中序遍历结果为:D B G E A C H F;则应该能够得出后序遍历结果为:D G E B H F C A。分析这个问题,我们可以从先序、中序、后序遍历的特点和结果,结合题目中给出的典型例子,得出相关的规律;我的思路是:先由先序和中序遍历结果计算得到二叉树,之后用递归方法对二叉树进行后序遍历得出结果。(1)首先,由先序和中序遍历,我们是完全可以得到二叉树的构成的,这由两者的区别和联系所共同决定;我们以上面的例子来说明思路:① A B D E G C F H     可以被分成两个部分来看      A B D E G   and   C F H② D B G E A C H F                               D B G E A         C H F    以先序遍历为基础,我们知道先序遍历一定先遍历根节点,由①可知 A 一定是根节点,则在先序和中序遍历过程中,两者都要先遍历完 A 的左子树,再去遍历 A 的右子树;所以,很明显地,在中序遍历中,A 将会列表分为两半:D,B,G,E 以及 C,H,F。其中 D,B,G,E 均为 A 的左子树节点,而 C,H,F 均为 A 的右子树的节点。    我们将视线转回先序遍历,由于遍历根节点 A 之后,紧接着按照先序遍历一定会去遍历A的左子树的根节点,即节点B;又因为 B,D,E,G 均为 A 的左子树节点,根据先序遍历的特点,在 A 的左子树遍历完成之后,立刻就会去遍历 A 的右子树的根节点,也就是第二个部分中①的第一个节点 C(应注意②中的第二部分第一个节点也为C仅仅是这一题的情况,不能由此断言A的右子树根节点为C,而应根据先序遍历的首位C来判断)。    这样,我们就可以将原有的整个二叉树,在除去根节点 A 之后,得到它的两个子树及其各自的根节点 B 和 C,而下面的思路就很明了,使用递归方法,分别对B、C两个子树进行左右分解,注意判断递归条件和不断建立新节点,这样就可以获取整个二叉树了。再递归函数中,分情况讨论可以分为以下几种:1)A B D E G C F H   D B G E A C H F (完整类型)2)A C F H   A C H F     (A不含有左子树)3)A B D E G   D B G E A   (A不含有右子树)4)A   A  (A不含有左右子树,即A为叶节点)(2)在获取整个二叉树后,使用递归方法写后序遍历函数,对二叉树进行后序遍历,即可得到正确结果。示例代码如下:
def tree_establish(Node, Preorder, Inorder, n):   # 建立二叉树(Node为根节点,n为节点数量)    i = Inorder.index(Preorder[0])    if i == 0:                          # 根节点 A 不存在左子树        if i + 1 <= n - 1:                      # 根节点 A 存在右子树(C为根节点)            Node.rchild = node(Preorder[i+1])            tree_establish(Node.rchild, Preorder[i+1:n:1], Inorder[i+1:n:1], n-1)        else:                                   # 根节点A不存在左右节点(子树)            return 1    else:                               # 根节点 A 存在左子树(B为根节点)        if i + 1 <= n - 1:                      # 根节点 A 含有左右子树            Node.lchild = node(Preorder[1])            Node.rchild = node(Preorder[i+1])            tree_establish(Node.lchild, Preorder[1:i+1:1], Inorder[0:i:1], i)            tree_establish(Node.rchild, Preorder[i+1:n:1], Inorder[i+1:n:1], n-i-1)        else:                                   # 根节点 A 不含有右子树            Node.lchild = node(Preorder[1])            tree_establish(Node.lchild, Preorder[1:i+1:1], Inorder[0:i:1], i)def post_order_probing(Node):       # 后序遍历函数(递归实现)    if Node is None:        return 0    else:        if Node.lchild:            post_order_probing(Node.lchild)        if Node.rchild:            post_order_probing(Node.rchild)        print(Node.elem, end=' ')class node(object):              # 定义节点类    def __init__(self, elem=None, lchild=None, rchild=None, par=None):        self.elem = elem        self.lchild = lchild        self.rchild = rchild        self.par = parclass tree(object):              # 定义树类    def __init__(self, root=node()):        self.root = rootpreorder = [i for i in input().split()]    # 输入先序遍历结果inorder = [i for i in input().split()]     # 输入中序遍历结果N = len(preorder)MyTree = tree(node(preorder[0]))           # 初始化二叉树tree_establish(MyTree.root, preorder, inorder, N)  # 建立二叉树post_order_probing(MyTree.root)                    # 打印后序遍历结果(最后有个空格)

 

转载地址:http://ahvrj.baihongyu.com/

你可能感兴趣的文章
小甲鱼Python第十九讲(函数,我的地盘听我的)
查看>>
小甲鱼python第二十讲(内嵌函数和闭包)
查看>>
小甲鱼Python第二十一讲(lambda表达式)
查看>>
小甲鱼Python第二十三讲、第二十四讲(递归-这帮小兔崽子、汉诺塔)
查看>>
小甲鱼Python第二十七讲(集合)
查看>>
可调谐半导体激光器的窄线宽测试及压缩
查看>>
matlab中 %d,%f,%c,%s
查看>>
常见的光纤接头汇总
查看>>
半导体激光器—问题整理(二)
查看>>
科研日记7.31
查看>>
zemax仿真二向色镜
查看>>
stm32单片机编程时extern的用法
查看>>
UART4和5的问题
查看>>
Spring框架中在并发访问时的线程安全性
查看>>
网站部署
查看>>
什么情况下会发生栈内存溢出。
查看>>
何为去中心化
查看>>
缓存一致性:写策略
查看>>
Cache一致性:MESI
查看>>
缓存一致性:写未命中
查看>>