/*
* 题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
* 例如输入前序遍历序列{a,b,d,c,e,f}和中序遍历序列{d,b,a,e,c,f},则重建二叉树并返回。
* 思路:根据题目给出的前序遍历、后序遍历数组,首先找出根节点
* 然后再根据中序遍历找到左子树和右子树的长度,分别构造出左右子树的前序遍历和中序遍历序列
* 最后分别对左右子树采取递归,递归跳出的条件是序列长度为1.
* */
class Node {
Nodeleft= null;
Noderight= null;
char value;
}
public classtree {
/**
* 根据前序遍历和中序遍历重建二叉树子树
* @param preOrder前序遍历数组
* @param start子树起始位置
* @param inOrder中序遍历数组
* @param end中序遍历结束位置
* @param length子树节点树
* @return子树的根节点
*/
public static Node buildTree(char[] preOrder,int start,
char[] inOrder,int end, int length) {
//参数验证
if (preOrder ==null || preOrder.length == 0 || inOrder ==null
||inOrder.length== 0 || length <= 0) {
return null;
}
//建立子树根节点
char value =preOrder[start];
Noderoot = newNode();
root.value = value;
//递归终止条件:子树只有一个节点
if (length == 1)
return root;
//分拆子树的左子树和右子树,从前序序列找根来分割中序序列
int i = 0;
while (i < length) {
if (value == inOrder[end -i]) {
break;
}
i++;
}
//建立子树的左子树,我们需要记录被分割中序序列的开头和结尾坐标,这个范围对前序序列也适用
root.left = buildTree(preOrder,start + 1, inOrder, end - i - 1, length - 1 - i);
//建立子树的右子树。
root.right = buildTree(preOrder,start + length - i, inOrder, end, i );
return root;
}
public static void main(String[] args) {
char[] preOrder =new char[] {'a','b', 'd', 'c', 'e', 'f'};
char[] inOrder =new char[] {'d','b', 'a', 'e', 'c', 'f'};
Noderoot = buildTree(preOrder, 0, inOrder, inOrder.length - 1, inOrder.length);
}
}