二叉树-已知前序序列和中序序列,求后序序列

本文介绍了一种通过递归算法实现从给定的前序和中序遍历序列生成对应的后序遍历序列的方法。重点在于理解如何利用递归思想来划分二叉树,并逐步构造出完整的后序遍历序列。

package test;

public class SubTree {
 /**
  * 已知二叉树前序和中序,求后序
  * @param pre
  * @param mid
  * @param last
  * @param i
  */

  public static int i =0;//i:表示要插入后序序列的位置对于生成的后序序列,应该从最后位置开始写,
// 所以在main中将值赋成mid.length-1。这里将i定义成全局变量,是因为如果序列长度为1时,
//  i--无法返回i的值,暂时没有想到其它方法。Integer已经试过,不行。
 public void getLast(char[] pre, char[] mid, char[] last){
  if(pre.length<=1){//如果序列的长度小于等于1,将该序列中的元素插入last序列,然后返回
   last[i]=pre[0];
   System.out.println(i);
   i--;
   return;
     }
   
  else{//如果序列长度大于1,则将二叉树的根插入last序列,然后将序列分成两个,分别进行递归
   last[i] = pre[0];
   i--;
   
   int j =0;
   for(;j<mid.length&&pre[0]!=mid[j];j++);//在mid中找到根元素,从此处将mid分成两部分
   
   char[] newmid1 = new char[j];
   char[] newmid2 = new char[mid.length-j-1];
   
   char[] newpre1 = new char[j];
   char[] newpre2= new char[mid.length-j-1];
   
   if(j<mid.length-1){//求后子树的后序序列
    for(int n=0;n<mid.length-j-1;n++){
     newmid2[n] = mid[n+j+1];
     newpre2[n] = pre[n+j+1];
    }
    getLast(newpre2,newmid2,last);
   }
   
   if(j>0){//求前子树的后序序列
    for(int m =0;m<j;m++){
     newmid1[m]=mid[m];
     newpre1[m]=pre[m+1];
    }
    getLast(newpre1,newmid1,last);
   }
  }//else
 }
 
 public static void main(String[] args){
  
  SubTree st = new SubTree();
  char[] pre = {'A','B','C','D','E','F','G'};
  char[] mid = {'C','D','B','E','A','G','F'};
////  
//  char[] pre = {'B','C','D','E'};
//  char[] mid = {'C','D','B','E'};
  
//  char[] pre = {'F','G'};
//  char[] mid = {'G','F'};

  
  char[] last = new char[pre.length];
   i = mid.length-1;
  st.getLast(pre, mid,last);
  for(int j=0;j<last.length;j++)
   System.out.print(last[j]);
  
 }

}
输出结果:DCEBGFA

证明已知一棵二叉树前序序列序列可唯一确定该二叉树,可从以下方面进行分析。 前遍历的顺是:根节点 -> 左子树 -> 右子树;中遍历的顺是:左子树 -> 根节点 -> 右子树。 在前序序列中,第一个元素必定是二叉树的根节点。设前序序列为 `preorder`,中序列为 `inorder`,`preorder[0]` 就是根节点的值。 在中序列里找到根节点的位置,假设为 `index`。由于中遍历的特性,`inorder` 中 `inorder[:index]` 部分就是左子树的中序列,`inorder[index + 1:]` 就是右子树的中序列。 根据左子树右子树的中序列的长度,可以在前序序列中划分出左子树右子树的前序序列。左子树前序序列的长度左子树中序列的长度相同,右子树同理。这样就得到了左子树的前序序列 `preorder[1:index + 1]` 右子树的前序序列 `preorder[index + 1:]`。 对于左子树右子树,又可以重复上述过程,因为它们同样是二叉树,其各自的前序序列序列也能按照此方法不断确定子树的根节点以及左右子树。 以下是实现根据前序列构建二叉树的 Python 代码: ```python # 定义二叉树节点类 class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def buildTree(preorder, inorder): if not preorder or not inorder: return None # 前序序列的第一个元素是根节点的值 root_val = preorder[0] root = TreeNode(root_val) # 在中序列中找到根节点的位置 index = inorder.index(root_val) # 递归构建左子树 root.left = buildTree(preorder[1:index + 1], inorder[:index]) # 递归构建右子树 root.right = buildTree(preorder[index + 1:], inorder[index + 1:]) return root ``` 综上所述,通过前序序列确定根节点,再利用中序列划分左右子树,并且不断递归这个过程,能够唯一确定一棵二叉树
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值