写在前面
- 作者在写这道题目之前,已经大约有大半年的时间没有看“树”了,所以有同样情况的兄弟们,请先参考学习有关树与二叉树及其遍历的基本概念,再回到这篇文章中学习,这里将不再对树的概念和特性进行科普。
题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
思路
- 先了解二叉树的三种遍历方式,前序遍历,中序遍历和后序遍历。
- 题目中给出了前序遍历和中序遍历,前序遍历的特点:前序遍历结果中第一个元素是根节点,接下来的是左子树和右子树。中序遍历特点:先是左子树,然后是根节点,然后是右子树。
- 我们可以通过前序遍历结果找到当前的“根”,也就是结果中的第一个元素,记为root。
- 用root到中序遍历的结果中寻找相同元素,并返回该元素下标,记为index。
- 由于中序遍历的结果为:先是左子树,然后根节点,最后是右子树。所以可以确定,index向左的部分,为root下的左子树,index向右的部分为index下的右子树。
- 根据已经在中序遍历中分好的左右子树的长度,到前序遍历结果中,将前序遍历中的左右子树区分开。
- 拥有了左子树的前序遍历结果和中序遍历结果,只需要将当前root的左子树赋值为递归程序的返回值,右子树同理。
- 最后只要返回当前root即可,下面是大概的解释图,看不懂可以留言或者私聊我,给你讲懂:
代码演示
这是节点类
class TreeNode {
int value;
TreeNode leftNode;
TreeNode rightNode;
public TreeNode(int value) {
this.value = value;
}
}
这是具体的转换过程,一些细节写在注释中了
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
if (pre == null || in == null) {
return null;
}
List<Integer> preList = new ArrayList<>(); // 因为给进来的参数是数组,我把他转化为list,方便处理
List<Integer> inList = new ArrayList<>();
for (int index = 0; index < pre.length; index++) {
preList.add(pre[index]);
inList.add(in[index]);
}
return ReTree(preList, inList);
}
private TreeNode ReTree(List<Integer> pre, List<Integer> in) { // 这个是真正的递归程序
if (pre == null || in == null) {
return null;
}
int rootValue = pre.get(0); // 找到前序遍历结果中的第一个元素,也就是Root
System.out.println("rootValue : " + rootValue);
TreeNode root = new TreeNode(rootValue); // 建立根节点,并赋值
int index = in.indexOf(rootValue); // 找到中序遍历中对应元素的下标
if (index == 0) { // 这里的两个if-else是为了确定元素是否存在左右子树
// 左子树为null // 如果不存在左右子树,参数为null
root.leftNode = ReTree(null, null);
} else { // 这一步给左子树赋值
root.leftNode = ReTree(pre.subList(1, index + 1), in.subList(0, index));
}
if (index + 1 == in.size()) {
// 右子树为null
root.rightNode = ReTree(null, null);
} else { // 这一步给右子树赋值
root.rightNode = ReTree(pre.subList(index + 1, pre.size()), in.subList(index + 1, in.size()));
}
return root; // 向上返回根节点作为结果
}
这是输出树的代码(中序输出),很容易写,用作验证结果。
public void printTree(TreeNode root) {
if (root == null) {
return;
}
printTree(root.leftNode);
System.out.println(root.value);
printTree(root.rightNode);
}
总结
- 能看到这里的朋友,先谢谢你,你尊重原创,尊重知识。
- 如果有什么疑问或者我的文章有些的不好或不准确的地方,欢迎留言或私信我!