40.前序和中序遍历重建二叉树

题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。

假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

解析:
①首先根据前序遍历可知,前序序列的第一个元素为根节点,即1为根节点;
②在中序遍历序列中找到1所在的位置,1之前的序列为左子树,即{4,7,2}为根节点的左子树。1之后的序列为右子树,即{5,3,8,6}为根节点的右子树;
③左子树{4,7,2}对应前序遍历中的[2,4,7},所以2为根节点,右子树{5,3,8,6}对应前序遍历中的{3,5,6,8},所以5为根节点;
④重复②③步骤,即进入递归求解。

public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
  if (pre == null || in == null)    return null;
  TreeNode root = null;
  root = rebuild (pre,0,pre.length-1,in,0,in.length-1);//重建二叉树
  return root;
 }
 //核心递归函数
 public TreeNode rebuild(int[] pre, int startpre, int endpre, int[] in, int startin, int endin){
  if (startpre > endpre || startin > endin)   return null;//递归结束条件
  TreeNode root = new TreeNode(pre[startpre]);//前序遍历序列中第一个元素为根节点
  for (int i = startin; i <= endin; i++){
   if (in[i] == pre[startpre]){//pre[startpre]为根,找出其对应在中序遍历in中的根元素
       //对根节点的左子树进行递归操作,注意此时根节点的位置
    root.left = rebuild(pre,startpre+1,startpre+i-startin,in,startin,i-1);
       //对根节点的右子树进行递归操作
    root.right = rebuild(pre,startpre+i-startin+1,endpre,in,i+1,endin);
   }
  }
  return root;
 }

拓展:中序 后序遍历构造二叉树
操作跟上面一样

public TreeNode buildTree(int[] inorder, int[] postorder) {
  if (inorder == null || postorder == null)  return null;
  TreeNode root = null;
  root = buildTree(inorder,0,inorder.length-1,postorder,0,postorder.length-1);
  return root;
 }
 
 public TreeNode buildTree(int[] inorder,int startin,int endin,int[] postorder,int startpost,int endpost){
  if (startin > endin || startpost > endpost)  return null;
  TreeNode node = new TreeNode(postorder[endpost]);
  for (int i = startin; i <= endin;i++){
   if (inorder[startin] == postorder[endpost]){
    node.left = buildTree(inorder,startin,i-1,postorder,startpost,i-startin-1+startpost);
    node.right = buildTree(inorder,i+1,endin,postorder,i-startin+startpost,endpost-1);
   }
  }
  return node;
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值