转载请注明出处:https://blog.csdn.net/loiter2/article/details/107523272
该文章只是用来记录一下刷题过程,本文的记录和解答用的Java语言。
1、题目分析
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
public class TreeLinkNode {
int val;
TreeLinkNode left = null;
TreeLinkNode right = null;
TreeLinkNode(int val) {
this.val = val;
}
}
上述代码是题目给出的二叉树结点
- 首先明白一点:
前序遍历是根左右;
中序遍历是左根右; - 因此前序遍历结果的第一个点,肯定是二叉树的根结点,如题目例子,根结点肯定为1。
那么在中序遍历结果中找到结点1,根据左根右的特性,1左侧的就是根结点(结点1)的左子树,右侧是右子树,
即4 7 2 /// 1 /// 5 3 8 6
再根据左子树和右子树结点的数量,可以得到前序遍历结果中的划分为:
1 /// 2 4 7 /// 3 5 6 8 - 然后要明白的第二点是,二叉树的左右子树,都仍然还是一棵二叉树。因此分别对左右子树重复上述过程即可
从上面的分析易得,应该采用递归的方法,不断构建根结点及其左右子树即可
2、代码实现
作为学习,最好看了上面的思路后,自己去实现代码,学习效果更好。
import java.util.Arrays;
public class SolutionJZ4 {
public TreeNode reConstructBinaryTree(int [] pre, int [] in) {
//递归终止条件,刚接触递归,不太容易找到递归终止条件时,就用一个例子不断往下试,去发现终止条件
if (pre.length == 0 || in.length == 0){
return null;
}
int rootValue = pre[0];
//找到根结点在中序遍历结果中的位置
int indexOfRootValue = findRootIndex(rootValue, in);
int [] leftPre = Arrays.copyOfRange(pre, 1, 1+indexOfRootValue);
int [] leftIn = Arrays.copyOfRange(in, 0, indexOfRootValue);
int [] rightPre = Arrays.copyOfRange(pre, indexOfRootValue+1, pre.length);
int [] rightIn = Arrays.copyOfRange(in, indexOfRootValue+1, in.length);
//递归构建子树
TreeNode root = new TreeNode(rootValue);
root.left = reConstructBinaryTree(leftPre, leftIn);
root.right = reConstructBinaryTree(rightPre, rightIn);
return root;
}
//该方法其实也完全可以直接在主程序中通过两行代码实现,不过模块化可能更好一点
private int findRootIndex(int rootValue, int[] in) {
for (int i = 0; i<in.length; i++){
if (rootValue == in[i]){
return i;
}
}
return -1;
}
}