如果已知一个二叉树的前序、中序遍历结果,要重建一个二叉树,步骤如下:
二叉树的四种遍历方式
例:
二叉树的前序遍历结果:{1,2,4,7,3,5,6,8};
中序遍历结果:{4,7,2,1,5,3,8,6};
我们知道树的前序遍历第一个数就是根节点,而在中序遍历中,前面是左子树,中间是根节点,后面是右子树,于是对于这个二叉树:
1、根节点:1
2、左子树(就是在中序遍历中找到根节点,前面的数就是左子树的所有节点):中序遍历中的{4,7,2},于是在前序中就是{2,4,7};
3、右子树:中序遍历中的{5,3,8,6},于是在前序中就是{3,5,6,8};
4、对左子树、右子树的前序中序结果递归进行前面的操作;
/**
* 根据重建一个二叉树主方法
* @param pre 前序遍历的数组
* @param inf 中序遍历的数组
* @return
*/
public static Tree.Entry rebuild(int [] pre,int [] inf) {
if(pre == null || inf == null){
return null;
}
Tree<Integer>.Entry root = core(pre, inf, 0, pre.length-1, 0, inf.length-1);
return root;
}
/**
* 核心函数
* @param pre
* @param inf
* @param preStart
* @param preEnd
* @param infStart
* @param infEnd
* @return
*/
private static Tree.Entry core(int[] pre, int[] inf, int preStart, int preEnd, int infStart, int infEnd) {
//根节点
Tree<Integer>.Entry root = new Tree().new Entry(pre[preStart]);
root.left = null;
root.right = null;
//递归的终点,递归的终止条件
if (preStart == preEnd && infStart == infEnd) {
return root;
}
//找到当前根在中序遍历数组的位置
int index = 0;
for(index = infStart; index < infEnd; index++){
if (pre[preStart] == inf[index]) {
break;
}
}
int leifLength = index - infStart; //左子树长度
int rightLength = infEnd - index; //右子树长度
if (leifLength > 0) {
//递归左子树
root.left = core(pre, inf, preStart+1, preStart+leifLength, infStart, index-1);
}
if (rightLength > 0) {
//递归右子树
root.right = core(pre, inf, preStart+1+leifLength, preEnd, index+1, infEnd);
}
return root; //返回整个树的根节点
}
测试代码:
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};
Tree<Integer> tree = new Tree<>();
tree.DLR(rebuild(pre,in));
System.out.println();
tree.LDR(rebuild(pre,in));
}
运行结果:
1 2 4 7 3 5 6 8
4 7 2 1 5 3 8 6