1、根据前序和中序遍历重构二叉树
1.1 题目
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
1.2 题目分析
在二叉树的前序遍历序列中,第一个数字总是树的根结点的值。但在中序遍历序列中,根结点的值在序列的中间,左子树的结点的值位于根结点的值的右边,而右子树的结点的值位于根结点的值的右边。因此我们需要扫描中序遍历序列,找到根结点的值,也就区分出左右子树的大小、位置。
1.3 代码实现
import java.util.HashMap;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(
int x) { val = x; }
}
public class ReconstructTree {
public static TreeNode
reConstructBinaryTree(
int [] pre,
int []
in) {
if(pre==
null &&
in==
null){
return null;
}
HashMap<Integer, Integer> map =
new HashMap<>();
for (
int i =
0; i <
in.length; i++) {
map.put(
in[i], i);
}
return solve(pre,
in,
0,pre.length-
1,
0,
in.length-
1,map);
}
public static TreeNode
solve(
int[] pre,
int[]
in,
int preL,
int preR,
int inL,
int inR,HashMap<Integer, Integer> map){
if(preL>preR||inL>inR){
return null;
}
TreeNode head =
new TreeNode(pre[preL]);
int numl = map.
get(pre[preL]);
head.left = solve(pre,
in, preL+
1, preL+numl-inL, inL, numl-
1,map);
head.right = solve(pre,
in, preL+numl-inL+
1, preR, numl+
1, inR,map);
return head;
}
public static void main(String[] args) {
int[] a = {
1,
2,
4,
7,
3,
5,
6,
8};
int[] b = {
4,
7,
2,
1,
5,
3,
8,
6};
TreeNode node = reConstructBinaryTree(a, b);
}
}
2、根据中序和后序遍历重构二叉树
2.1 题目分析
中序和后序重构的过程与先序和中序的过程类似。先序和中序的过程是用先序数组最左的值来对中序数组进行划分,因为这里头节点的值。后序数组中头节点的值是后序数组最右的值,所以用后序最右的值来划分中序数组。
2.2 代码实现
public static TreeNode
inPosToTree(
int[]
in,
int[] pos){
if(
in==
null || pos==
null){
return null;
}
HashMap<Integer, Integer> map =
new HashMap<>();
for (
int i =
0; i <
in.length; i++) {
map.put(
in[i], i);
}
return solve2(
in, pos,
0,
in.length-
1,
0, pos.length-
1,map);
}
public static TreeNode
solve2(
int[]
in,
int[] pos,
int inL,
int inR,
int posL,
int posR,HashMap<Integer, Integer> map){
if(inL>inR||posL>posR){
return null;
}
TreeNode node =
new TreeNode(pos[posR]);
int num = map.
get(node.val);
node.right = solve2(
in, pos, num+
1, inR, posR+num-inR, posR-
1,map);
node.left = solve2(
in, pos, inL, num-
1, posL, posR+num-
1-inR, map);
return node;
}
3、通过先序和后序重构二叉树
3.1 题目
通过先序和后序重构二叉树,但大多数情况下并不能通过这两个数组把原来的树重构出来。这是因为很多结构不同的树中,先序与后序数组是一样的。
3.2 题目分析
然后需要分析出什么样的树可以被先序和后序数组重建,如果一棵二叉树除叶节点之外,其他所有的节点都有左孩子和右孩子,只有这样的树才可以被先序和后序数组重构出来。最后通过划分左右子树各自的先序与后序数组的方式重构整棵树。
3.3 代码实现
//根据前序和后序遍历重构二叉树
public static TreeNode proPosToTree(
int[] pro,
int[]
pos){
if(pro==null ||
pos==null){
return null;
}
HashMap<Integer, Integer>
map = new HashMap<>();
for (
int i =
0; i <
pos.
length; i++) {
map.put(
pos[i], i);
}
return solve3(pro,
pos,
0, pro.
length-
1,
0,
pos.
length-
1,
map);
}
public static TreeNode solve3(
int[] pro,
int[]
pos,
int proL,
int proR,
int posL,
int posR,HashMap<Integer, Integer>
map){
TreeNode head = new TreeNode(
pos[posR--]);
if(proL==proR){
return head;
}
int num =
map.get(pro[++proL]);
head.left = solve3(pro,
pos, proL, proL+num-posL, posL, num,
map);
head.right = solve3(pro,
pos, proL+num-posL+
1, proR, num+
1, posR,
map);
return head;
}