前言:大家都知道,一颗二叉树可以有三种遍历方式,前序,中序及后遍
历。要重建一颗二叉树至少需要知道它的两种遍历结果,其中中序
遍历是必不可少的,不然是不能重建出一颗二叉树的。
本题已知前序遍历及中序遍历构建二叉树,那如果已知中序遍历及
后序遍历重构二叉树,其解题思路相同。
思路:先根据前序遍历的第一个值(根节点)找到在中序遍历中根节点的
位置,以此可判断出中序遍历中,根节点左边的节点为左子树中的
节点,右边的在右子树中,以此递归构建即可。
话不多说,代码如下:
//节点类
public class BinaryTreeNode {
int value;
BinaryTreeNode left;
BinaryTreeNode right;
public BinaryTreeNode() {
this.value=0;
this.left=null;
this.right=null;
}
public BinaryTreeNode(int value) {
this.value=value;
}
}
public class Main {
public static void main(String []args) throws Exception {
Main m=new Main();
int []preorder= {1,2,4,7,3,5,6,8};
int []inorder= {4,7,2,1,5,3,8,6};
int len=preorder.length;
BinaryTreeNode root=new BinaryTreeNode();
root=m.Construct(preorder,inorder);
m.lastorderTravel(root);
}
//判断前序及中序遍历是否输入有误
public BinaryTreeNode Construct(int []preorder,int []inorder)throws Exception {
if(preorder.length==0||inorder.length==0||preorder.length!=inorder.length) {
throw new Exception("输入有误无法构成二叉树");
}
return ConstructTree(preorder,inorder,0,preorder.length-1,0,inorder.length-1);
}
/***********************************
*重建二叉树,返回二叉树根节点
*prestart为前序遍历开始位置
*preend为前序遍历结束位置
*instart为中序遍历开始位置
*inend为中序遍历结束位置
***********************************/
public BinaryTreeNode ConstructTree(int[] preorder, int[] inorder,
int prestart, int preend, int instart, int inend) throws Exception{
int rootValue=preorder[prestart]; //根节点的值
BinaryTreeNode root=new BinaryTreeNode(rootValue);
//找到中序遍历中根节点的位置
int rootinorder=instart;
for(int i=instart;i<=inend;i++) {
if(rootValue==inorder[i]) {
rootinorder=i;
break;
}
if(i==inend&&rootValue!=inorder[i]) {
throw new Exception("输入有误无法构成二叉树");
}
}
int leftlen=rootinorder-instart;//左子树长度
int leftprelen=prestart+leftlen;//前序遍历中左子树结束位置
//递归构建二叉树
if(rootinorder>instart) {
root.left=ConstructTree(preorder,inorder,
prestart+1,leftprelen,instart,rootinorder-1);
}
if(rootinorder<inend) {
root.right=ConstructTree(preorder,inorder,
leftprelen+1,preend,rootinorder+1,inend);
}
return root;
}
//后序遍历输出二叉树
public void lastorderTravel(BinaryTreeNode root) {
if(root==null)return;
if(root.left!=null)lastorderTravel(root.left);
if(root.right!=null)lastorderTravel(root.right);
System.out.print(root.value+" ");
}
}