重建二叉树
题目如下:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
分析(引用一个博主的,讲的特别清晰):
二叉树的前序遍历顺序是:先访问根节点,然后前序遍历左子树,再前序遍历右子树。
中序遍历顺序是:中序遍历根节点的左子树,然后是访问根节点,最后中序遍历右子树。
1、二叉树的前序遍历序列一定是该树的根节点
2、中序遍历序列中根节点前面一定是该树的左子树,后面是该树的右子树
从上面可知,题目中前序遍历的第一个节点{1}一定是这棵二叉树的根节点,根据中序遍历序列,可以发现中序遍历序列中节点{1}之前的{4,7,2}是这棵二叉树的左子树,{5,3,8,6}是这棵二叉树的右子树。然后,对于左子树,递归地把前序子序列{2,4,7}和中序子序列{4,7,2}看成新的前序遍历和中序遍历序列。此时,对于这两个序列,该子树的根节点是{2},该子树的左子树为{4,7}、右子树为空,如此递归下去(即把当前子树当做树,又根据上述步骤分析)。{5,3,8,6}这棵右子树的分析也是这样。
————————————————
原文链接:https://blog.csdn.net/roycon/article/details/79772639
代码使用递归思想:
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
TreeNode root=reConstructBinaryTree(pre,0,pre.length-1,in,0,in.length-1);
return root; //返回根节点
}
//前序遍历{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}
private TreeNode reConstructBinaryTree(int [] pre,int startPre,int endPre,int [] in,int startIn,int endIn) {
**//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]){ //找出根节点所在的中序数组的位置
root.left=reConstructBinaryTree(pre,startPre+1,startPre+i-startIn,in,startIn,i-1); //递归调用左子树
root.right=reConstructBinaryTree(pre,i-startIn+startPre+1,endPre,in,i+1,endIn);//递归调用右子树
break; //找到新的前序数组和新的中序数组,任务完成,结束循环
}
return root;
}
}