前中序判断后序(中后序判断前序) python

已知前序[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)

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值