题目:输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树,假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如,输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历{4,7,2,1,5,3,8,6},则重建如图2.6所示的二叉树并输出它的头节点。
分析:
前序遍历:先根,再左,后右;
中序遍历:先左,再根,后右。
那么前序遍历的第一个是根,在中序遍历中找到根位置,即可确定左右子树的分布。例如:
前序:1为root 数组表示根,左,右为: pre[0],pre[0+1,0+3],pre[0+3+1,length-1]
中序:4,7,2为左子树,5,3,8,6为右子树。数组表示根,左,右: in[3],in[0,2],in[3+1,lengh-1]
设index为根结点在中序遍历中的位置,前序遍历起始位置为ps,pe,中序is,ie那么上面在前序、中序中根左右可化简为以下表示:
首先:左子树个数应为index-is(3-0)
前序表示:pre[ps],pre[ps+1,ps+index-is],pre[ps+index-is+1,pe]
后序表示:in[is],in[is,index-1],in[index+1,ie]
那么程序如下:
package main;
public class seven_createTree {
/**
* 定义二叉树节点,包括节点值,左右子树。
*/
class TreeNode{
int val;
TreeNode left;
TreeNode right;
}
public static void main(String[] args){
seven_createTree seven_createTree=new seven_createTree();
int[] pre={1,2,4,7,3,5,6,8};
int[] in={4,7,2,1,5,3,8,6};
TreeNode node = seven_createTree.reConstructBinaryTree(pre,in);
seven_createTree.printTree(node);
}
/**
* 给定二叉树的前序遍历和中序遍历,重构二叉树
*/
/**
*
* @param pre 前序遍历
* @param in 中序遍历
* @return
*/
public TreeNode reConstructBinaryTree(int[] pre,int[] in){
/**
* 输入合法性判断,不可为空,且长度至少需要一致
*/
if(pre == null||in ==null||pre.length!=in.length){
return null;
}
return construct(pre,0,pre.length-1,in,0,in.length-1);
}
/**
*
* @param pre 前序遍历
* @param ps 前序遍历起点
* @param pe 前序遍历终点位置
* @param in 中序遍历
* @param is 中序遍历起点位置
* @param ie 中序遍历终点位置
* @return
*/
public TreeNode construct(int[] pre,int ps,int pe,int[] in,int is,int ie){
if(ps>pe)return null;
//取前序遍历的第一个数字就是根结点
int value=pre[ps];
//在中序遍历中寻找根节点,其前面是左子树,右边是右子树
int index = is;
while (index<=ie&&value!=in[index])
index++;
//若没有找到,则说明输入有误,抛出异常
if(index>ie)
throw new RuntimeException("Invalid Iuput!");
//创建当前节点,并为根结点赋值
TreeNode node = new TreeNode();
node.val = value;
//递归调用构造当前节点的左子树.此处的参数需要注意
//当前节点的左子树的个数为index-is
//左子树对应的前序遍历的位置在preOrder[ps+1,ps+index-is]
//左子树对应的中序遍历的位置在inOrder[is,index-1]
node.left = construct(pre,ps+1,ps+index-is,in,is,index-1);
//递归调用构造当前节点的左子树.此处的参数需要注意
//当前节点的右子树的个数为ie-index
//右子树对应的前序遍历位置在preOrder[ps+index-is+1,pe]
//右子树对应的中序遍历位置在inOrder[index+1,ie]
node.right = construct(pre,ps+index-is+1,pe,in,index+1,ie);
return node;
}
private void printTree(TreeNode root){
if(root!=null){
printTree(root.left);
System.out.println(root.val+" ");
printTree(root.right);
}
}
}
运行结果为(中序遍历):