题目
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
思路
1.树 用递归实现
2.前序遍历的第一个是根节点,然后根据这个根节点找到中序遍历中的根节点 同时判断左右子树。并且分别递归左右子树
3.递归的出口是pre的长度为0 (没有子树)或为1 (只有一个元素) --都要返回
代码
import java.util.*;
/**
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
//出口
if(pre.length == 0){
return null;
}
int rootVal = pre[0];
//数组长度仅为1的时候就要处理
if(pre.length == 1){
return new TreeNode(rootVal);
}
TreeNode root = new TreeNode(rootVal);
int rootIndex = 0;
for(int i =0;i<in.length;i++){
if(in[i]==rootVal){
rootIndex = i;
break;
}
}
//递归,假设root的左右子树都已经构建完毕,那么只要将左右子树安到root左右即可
//这里注意Arrays.copyOfRange(int[],start,end)是[)的区间
root.left = reConstructBinaryTree(Arrays.copyOfRange(pre,1,rootIndex+1),Arrays.copyOfRange(in,0,rootIndex));
root.right = reConstructBinaryTree(Arrays.copyOfRange(pre,rootIndex+1,pre.length),Arrays.copyOfRange(in,rootIndex+1,in.length));
return root;
}
}
总结
1.注意Arrays.copyOfRange(int[],start,end)是[)的区间
扩展:根据层序遍历及中序遍历重建二叉树 并且输出叶子节点和先序遍历 及后序遍历结果
题目描述
给定二叉树T(树深度不超过H<=10,深度从1开始,节点个数N<1024,节点编号1~N)的层序和中序遍历,输出T从左向右叶子节点以及树先序和后序遍历序列
输入描述:
输入两行,分别代表层序和中序遍历结果,节点编号按单个空格分开
输出描述:
依次输出 从左向右叶子节点 ,先序, 后序 遍历 。 节点编号按空格分开
示例1
输入
复制
3 5 4 2 6 7 1
2 5 3 6 4 7 1
输出
复制
2 6 1
3 5 2 4 6 7 1
2 5 6 1 7 4 3
思路
1.第一步建树:先根据层序遍历及中序遍历的部分找到每个子树的root。然后再递归按找root节点方法建左子树和右子树。
2.建树完成后,直接打印所需的结点。
代码
//用递归重建子树 通过层序和中序
/**
* 根据中序遍历和层次遍历重建一棵二叉树
* 中序遍历可以确定左子树和右子树的范围
* 层次遍历可以确定在一个范围的子树中的层级关系
* 故这二者的序列给定就一定可以唯一的确定一棵二叉树
*/
import java.util.*;
public class Main{
public static class TreeNode{
private int val;
private TreeNode left;
private TreeNode right;
public TreeNode(int x){
this.val = x;
}
}
public static TreeNode parseTree(int[] level,int[] in){
return parseDT(level,in,0,in.length-1);
}
public static TreeNode parseDT(int[] level,int[] in,int start,int end){
int rootIndex = findRoot(level,in,start,end);
if(rootIndex==-1){
return null;
}
TreeNode root = new TreeNode(in[rootIndex]);
root.left = parseDT(level,in,start,rootIndex-1);
root.right = parseDT(level,in,rootIndex+1,end);
return root;
}
public static int findRoot(int[] level,int[] in,int start,int end){
for(int i =0;i<level.length;i++){
for(int j=start;j<=end;j++){
if(level[i]==in[j]){
return j;
}
}
}
return -1;
}
//如果当前节点的左右子树都空,则是叶子节点,打印后直接返回
public static void printLeaf(TreeNode tree){
if(tree==null){
return;
}
if(tree.left==null&&tree.right==null){
System.out.print(tree.val+" ");
return;
}
printLeaf(tree.left);
printLeaf(tree.right);
}
public static void printPre(TreeNode tree){
if(tree==null){
return;
}
System.out.print(tree.val+" ");
printPre(tree.left);
printPre(tree.right);
}
public static void printPost(TreeNode tree){
if(tree==null){
return;
}
printPost(tree.left);
printPost(tree.right);
System.out.print(tree.val+" ");
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String[] a = sc.nextLine().split(" ");
String[] b = sc.nextLine().split(" ");
int[] level = new int[a.length];
int[] in = new int[b.length];
for(int i =0;i<a.length;i++){
level[i] = Integer.parseInt(a[i]);
in[i] = Integer.parseInt(b[i]);
}
TreeNode tree = parseTree(level,in);
printLeaf(tree);
System.out.println();
printPre(tree);
System.out.println();
printPost(tree);
}
}
总结
1.写代码最好能按函数划分 最好简洁明了
扩展:前序跟中序 得到后序遍历并打印
代码
import java.util.*;
public class Main{
public static class TreeNode{
private char val;
private TreeNode left;
private TreeNode right;
public TreeNode(char x){
this.val = x;
}
}
public static TreeNode parseTree(char[] pre,char[] in){
if(pre.length == 0){
return null;
}
char rootVal = pre[0];
if(pre.length == 1){
return new TreeNode(rootVal);
}
int rootIndex=-1;
for(int i =0;i<in.length;i++){
if(in[i]==rootVal){
rootIndex=i;
break;
}
}
TreeNode root = new TreeNode(rootVal);
root.left = parseTree(Arrays.copyOfRange(pre,1,rootIndex+1),Arrays.copyOfRange(in,0,rootIndex));
root.right = parseTree(Arrays.copyOfRange(pre,rootIndex+1,pre.length),Arrays.copyOfRange(in,rootIndex+1,in.length));
return root;
}
public static void post(TreeNode tree){
if(tree==null){
return;
}
post(tree.left);
post(tree.right);
System.out.print(tree.val);
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String[] input = sc.nextLine().split(" ");
char[] pre = input[0].toCharArray();
char[] in = input[1].toCharArray();
TreeNode tree = parseTree(pre,in);
post(tree);
}
}