重建二叉树
题目描述
-
给出一个二叉树的前序遍历和中序遍历,请重建该二叉树,返回根节点
-
样例输入:
- 前序 {1,2,4,7,3,5,6,8};
- 中序 {4,7,2,1,5,3,8,6};
算法思路
-
首先要明白前序和中序遍历的顺序:
- 前序遍历:根左右
- 中序遍历:左根右
- 也就是说前序遍历的第一个节点就是树的根节点
- 中序遍历根节点左边的节点全在左子树上,右边的节点全在右子树上
算法过程:
-
前序pre【】 {1,2,4,7,3,5,6,8};
-
中序 mid【】 {4,7,2,1,5,3,8,6};
-
首先根据先序遍历找到根节点,根据该节点在中序遍历中找到根节点的位置:
- 此时根节点的位置为mid【3】 = 1,
-
此时中序遍历根节点左边即为左子树的中序遍历,右边为右子树的中序遍历
- 左子树中序遍历:【4,7,2】
- 右子树中序遍历:【5,3,8,6】
-
同时我们也可以获取左右子树的前序遍历
- 左子树先序遍历:【2,4,7】
- 右子树先序遍历:【3,5,6,8】
-
之后我们再根据左子树的先序和中序遍历再去得到根节点的左孩子
-
根据右子树的先序中序遍历得到根节点的右孩子
-
到这我们就可以看到这就是递归的思想了!
实现:
public static int[] preNums = new int[]{1,2,4,7,3,5,6,8};
public static int[] midNums = new int[]{4,7,2,1,5,3,8,6};
public static TreeNode reconstructTree( int preBegin, int preEnd, int midBegin, int midEnd){
if(preBegin > preEnd || midBegin > midEnd) return null;
int rootIndex = 0; //根节点在中序遍历的位置
int rootData = preNums[preBegin];
TreeNode head = new TreeNode(rootData); //根节点
for(int i = midBegin; i <= midEnd; i++){
if(midNums[i] == rootData) {
rootIndex = i;
break;
}
}
int leftTreeLength = rootIndex - midBegin; //左子树的长度
int rightTreeLength = midEnd - rootIndex; //右子树的长度
head.left = reconstructTree(preBegin+1,preBegin+leftTreeLength,midBegin,rootIndex-1);
head.right = reconstructTree(preBegin+leftTreeLength+1,preEnd,rootIndex+1,midEnd);
return head;
}