描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
思路分析
- 二叉树左右子树也是二叉树,可考虑递归。
- 前序遍历:先访问根节点,再访问左子节点。
- 中序遍历:先访问左子节点,再访问根节点。
- 前序的第一个数字是数的根节点。因此假设该元素在中序的位置为i,则中序中i位置之前的是左子树的节点,后面的是右子树的节点。划分出根节点和左右子树集合后,用同样方法构建左右子树。
过程
- 先根据前序遍历序列的第一个数创建根节点
- 在中序遍历序列中找到根节点位置,确定左右子树节点数量
- 在中序和前序中划分左右子树,调用重构二叉树的函数
import sun.reflect.generics.tree.Tree;
/**
* @author Wang Zhaorong
* @date 2018/2/27.
*/
public class RebuildBinaryTree {
//内部类TreeNode
public class TreeNode
{
private int value;
private TreeNode left;
private TreeNode right;
public TreeNode(int value)
{
this.value = value;
}
}
//重构二叉树的函数,返回二叉树
public static TreeNode RebuildBinaryTree(int[] pre, int[] in)
{
//调用一个同名静态private函数
TreeNode root = RebuildBinaryTree(pre, 0, pre.length-1, in, 0, in.length-1 );
return root;
}
/**
* 根据前序中序数组构建二叉树,给出前序数组pre和中序数组in,再给在前序中序中节点的位置
* @param pre 前序数组
* @param startPre 节点在pre中的位置起点
* @param endPre 节点在pre中位置终点
* @param in 中序数组
* @param startIn 节点在pre中的位置起点
* @param endIn 节点在pre中位置终点
* */
private static TreeNode RebuildBinaryTree(int[] pre, int startPre, int endPre, int[] in, int startIn, int endIn)
{
if(startPre>endPre || startIn>endIn)
return null;
//前序pre的第一个元素是要构建的二叉树的根节点
TreeNode root = new RebuildBinaryTree().new TreeNode(pre[startPre]);
for(int i=0; i<=endIn;i++)
{
//找到根节点在中序in中的位置
if(in[i] == pre[startPre])
{
//根节点的左子树元素在pre中从startPre+1直到start+(i-startIn),在in中从startIn到i-1
root.left = RebuildBinaryTree(pre, startPre + 1, startPre + i - startIn, in, startIn, i - 1);
//根节点的左子树元素在pre中从startPre+(i-startIn)+1直到endPre,在in中从i+1到endIn
root.right = RebuildBinaryTree(pre, startPre + i - startIn + 1, endPre, in, i + 1, endIn); }
}
return root;
}
//按照前序递归打印treeNode,这也是二叉树的前序遍历方法
public static void printTree(TreeNode treeNode)
{
if(treeNode != null)
{
System.out.println(treeNode.value);
printTree(treeNode.left);
printTree(treeNode.right);
}
else return;
}
public static void main(String[] args)
{
int[] pre = {1,2,4,7,3,5,6,8};
int[] in = {4,7,2,1,5,3,8,6};
TreeNode t = RebuildBinaryTree(pre, in);
printTree(t);
}
}