题目:输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如,输入前序遍历序列{1,2, 4, 7,3, 5, 6, 8}和中序遍历序列{4, 7,2, 1,5,3,8,6},则重建如图2.6所示的二叉树并输出它的头节点。
package JianZhiOffer;
/**
* 重建二叉树
* 输入某二叉树的前序遍历和中序遍历的结果,请重建该而擦函数。
* 假设输入的前序遍历和中序遍历的结果中不含重复的数字
*/
class BinaryTreeNode{
int val;
BinaryTreeNode left;
BinaryTreeNode right;
public BinaryTreeNode(int val)
{
this.val = val;
}
public BinaryTreeNode(int val, BinaryTreeNode left,BinaryTreeNode right)
{
this.val = val;
this.left = left;
this.right = right;
}
//前序遍历
public void preOrder()
{
preOrder(this);
}
private void preOrder(BinaryTreeNode node)
{
System.out.println(node.val);
if(node.left != null)
{
preOrder(node.left);
}
if(node.right != null)
{
preOrder(node.right);
}
}
//中序遍历
public void inOrder()
{
inOrder(this);
}
private void inOrder(BinaryTreeNode node)
{
if(node.left != null)
{
inOrder(node.left);
}
System.out.println(node.val);
if(node.right != null)
{
inOrder(node.right);
}
}
}
public class Problems_7 {
public static void main(String[] args) {
int[] preOrder = {1,2,4,7,3,5,6,8};
int[] inOrder = {4,7,2,1,5,3,8,6};
BinaryTreeNode root = Construct(preOrder, inOrder);
System.out.println("前序遍历:======");
root.preOrder();
System.out.println("中序遍历:======");
root.inOrder();
}
public static BinaryTreeNode Construct(int[] preOrder,int[] inOrder)
{
if(preOrder==null || inOrder == null || preOrder.length == 0 || inOrder.length == 0)
{
return null;
}
return ConstructCore(preOrder,0,preOrder.length-1,inOrder,0,inOrder.length-1);
}
private static BinaryTreeNode ConstructCore(int[] preOrder, int startPreOrder, int endPreOrder,
int[] inOrder, int startinOrder, int endinOrder) {
//前序遍历数组的第一个数字就是根节点
int rootValue = preOrder[startPreOrder];
BinaryTreeNode root = new BinaryTreeNode(rootValue,null,null);
//说明当前root的左右子树都为空
if(startPreOrder == endPreOrder && startinOrder == endinOrder)
{
return root;
}
//查找根节点中序遍历数组的位置
int rootInOrder = startinOrder;
while(rootInOrder <= endinOrder && rootValue != inOrder[rootInOrder])
{
rootInOrder++;
}
//循环结束后,rootInOrder指向中序遍历数组中的根节点的位置
//leftLength 代表根节点左侧有几个数字,也就是根节点的左子树的总节点数
int leftLength = rootInOrder - startinOrder;
//rightLength 代表根节点右侧有几个数字,也就是根节点的右子树的总节点数
int rightLength = endinOrder - rootInOrder;
//leftLength > 0 说明根节点的左子树的总节点数不为0,那么就开始构建左子树
if(leftLength > 0)
{
root.left = ConstructCore(preOrder,startPreOrder+1,startPreOrder+leftLength,
inOrder,startinOrder,rootInOrder-1);
}
//rightLength > 0 说明根节点的右子树的总节点数不为0,那么就开始构建右子树
if(rightLength > 0)
{
root.right =ConstructCore(preOrder,startPreOrder+leftLength+1,endPreOrder,
inOrder,rootInOrder+1,endinOrder);
}
return root;
}
}