1、 题目描述
输入某二叉树的前序遍历和中序遍历的结果,重建改二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
例如:给出
前序遍历preorder = [3,5,7,9,6,10,11]
中序遍历inorder = [7,5,9,3,10,6,11]
返回的二叉树:
3
/ \
5 6
/ \ / \
7 9 10 11
2、题目分析
什么是前序遍历和中序遍历?
前序遍历的顺序:根节点,左子树,右子树,每个子树的遍历顺序又是前序遍历。
中序遍历的顺序:左子树,根节点,右子树,每个子树的遍历书序又是中序遍历。
结论
1、二叉树的前序遍历中,第一个数字总是树的根节点值。
2、二叉树的中序遍历中,根节点的值位于序列的中间,左子树的序列位于根节点的左边,右子树的序列位于根节点的右边。
3、解题的核心思想
已知
前序遍历:[3,5,7,9,6,10,11]
中序遍历:[7,5,9,3,10,6,11]
思想
1、前序遍历的第一个节点是根节点的值
2、在中序遍历中找到根节点的位置,可以将前、中序列分成左子树和右子树的序列分别为,左子树的前序遍历:[5,7,9],左子树的中序遍历[7,5,9],右子树的前序遍历:[6,10,11],右子树的中序遍历:[10,6,11]
3、左子树的前中遍历和右子树的前中遍历又可以回到第1步,形成递归。
4、递归的出口是:当序列为空或者序列只有一个值时。
4、java实现
public class RecreateTree {
//二叉树的节点
private static class Node {
private int value;
private Node left;
private Node right;
public Node(int value, Node left, Node right) {
this.value = value;
this.left = left;
this.right = right;
}
public Node() {
}
}
/**
*
* @param preorder 前序序列 List
* @param preStart 前序序列开始下标
* @param preEnd 前序序列结束下标
* @param inorder 中序序列 List
* @param inStart 中序序列开始下标
* @param inEnd 中序序列结束下标
* @return
*/
private static Node recreat(List<Integer> preorder, int preStart, int preEnd,List<Integer> inorder, int inStart, int inEnd) {
//序列为空
if(preStart>preEnd) {
return null;
}
//序列只有一个值,返回根节点
if(preStart == preEnd){
return new Node(preorder.get(preStart),null,null);
}
//序列有多个值
//创建根节点
Node root = new Node(preorder.get(preStart),null,null);
//中序遍历中获得根节点的位置
int index = inorder.indexOf(preorder.get(preStart));
//构建左子树
//preorder, preStart+1, index 获得左子树的前序序列
//inorder, inStart, index-1 获得左子树的中序序列
root.left = recreat(preorder, preStart+1, index, inorder, inStart, index-1);
//构建右子树
//preorder, index+1, preEnd 获得右子树的前序序列
//inorder, index+1, inEnd 获得右子树的中序序列
root.right = recreat(preorder, index+1, preEnd, inorder, index+1, inEnd);
return root;
}
public static void main(String[] args) {
List<Integer> preorder = new ArrayList<>();
List<Integer> inorder = new ArrayList<>();
preorder.add(3);
preorder.add(5);
preorder.add(7);
preorder.add(9);
preorder.add(6);
preorder.add(10);
preorder.add(11);
inorder.add(7);
inorder.add(5);
inorder.add(9);
inorder.add(3);
inorder.add(10);
inorder.add(6);
inorder.add(11);
Node root = recreat(preorder,0,preorder.size()-1,inorder,0,preorder.size()-1);
System.out.println(root);
}
}