重建二叉树

白昼怎懂夜的黑 提交于 2019-12-10 15:16:52

重建二叉树

题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
在这里插入图片描述

遍历方式

前序遍历:根->左子树->右子树
中序遍历:左子树-> 根 -> 右子树
后序遍历:左子树 —> 右子树 —> 根结点
层次遍历:按层次遍历

重建二叉树

中序+其他任意一种遍历==唯一二叉树

解题思路 递归

/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */

1.找到根结点

前序遍历第一个节点为根节点,后序遍历最后一个点为根节点。 题目中根节点为1

2.确定左右子树

中序遍历中找到根节点的位置,根节点左边为左子树(4,7,2),右边的为右子树(5,3,8,6)

3.递归

左右子树分别看作一个新的树,对应新的前序和中序遍历序列(怎么确定新的遍历序列看接下来的代码),进行递归求解。

public class Solution {
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        if(startPre>endPre||startIn>endIn)
           return null;
        //前序遍历第一个点为根
       TreeNode root= reConstructBinaryTree(pre,in,0,pre.length-1,0,in.length-1);
        return root;
      
    }
    //递归
    private TreeNode reConstructBinaryTree(int [] pre,int [] in,int startPre,int endPre,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(pre[startPre]==in[i]){
            root.left=reConstructBinaryTree(pre,in,startPre+1,startPre+(i-startIn),startIn,i-1);
            root.right=reConstructBinaryTree(pre,in,(i-startIn)+startPre+1,endPre,i+1,endIn);
        }
         
    }
       return  root;
    }
}

代码解析

java不像python 对list 切片那么方便,因此我们只能引入四个变量来控制前序遍历的头尾index,和中序遍历的头尾index来控制子树区间。
root.left=reConstructBinaryTree(pre,in,startPre+1,startPre+(i-startIn),startIn,i-1);
左子树看作一个新的树,递归计算其根节点左子树的左右子树,一直递归直到startPre>endPre||startIn>endIn。
reConstructBinaryTree(pre,in,startPre+1,startPre+i-startIn,startIn,i-1);
方法的参数分别为前序序列数pre[],中序序列in[],左子树对应的前序序列的开始index是后移一位所以就是startPre+1,左子树对应的前序序列的结束index为startPre+(i-startIn),(i-startIn)表示左子树的个数也就是说中序遍历序列从第0个index开始到根节点index,(根节点index 为i)的长度,所以前序遍历的结束index是从前序遍历的开始index+左子树节点个数,接下来两个参数为中序左子树中序遍历的开始index startIn,结束index,i-1。

root.right=reConstructBinaryTree(pre,in,(i-startIn)+startPre+1,endPre,i+1,endIn);
右子树前序遍历开始index 为(i-startIn)+startPre+1 把左子树的前序遍历去掉就是右子树的前序遍历 所以在左子树的开始index startPre+1 再往右移(i-startIn)左子树点个数位就是右子树的开始index。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!