问题描述:给定一个前序遍历和一个中序遍历,重建一棵二叉树。如:
前序:a b d c e f
中序:d b a e c f
思路:根据前序,找出根节点a,然后根据中序,可以找出根节点a的左右子树,然后递归求a的左子树前序b d跟中序d b,a的右子树前序c e f跟中序e c f
package suda.alex.chapter3;
import java.util.Scanner;
public class RebuildTree {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
int n = scanner.nextInt();
String preStr = scanner.next();
String inStr = scanner.next();
char[] pre = preStr.toCharArray();
char[] in = inStr.toCharArray();
Node tree = reBuildTree(pre, in);
printTree(tree);
}
}
public static Node reBuildTree(char[] pre, char[] in) {
int n = pre.length; // 二叉树的节点数
Node root = new Node(pre[0]);
int leftLen = 0;
while (leftLen < n && in[leftLen] != pre[0]) { // 在中序中查找pre[0]出现的位置。注:pre[0]就是此时的根
leftLen++;
}
int rightLen = n - leftLen - 1;
char[] left1 = new char[leftLen]; // 查找到pre[0]之后,前序中的左子数序列。
char[] right1 = new char[rightLen]; // 前序中的右子数序列
char[] left2 = new char[leftLen]; // 中序中的左子数序列
char[] right2 = new char[rightLen];// 中序中的右子数序列
// 赋值
for (int i = 1; i <= leftLen; i++) {
left1[i - 1] = pre[i];
left2[i - 1] = in[i - 1];
}
for (int i = 0; i < rightLen; i++) {
right1[i] = pre[i + leftLen + 1];
right2[i] = in[i + leftLen + 1];
}
if (leftLen > 0) {
root.left = reBuildTree(left1, left2);
}
if (rightLen > 0) {
root.right = reBuildTree(right1, right2);
}
return root;
}
// 打印出二叉树 前序 用于验证生成的二叉树是否正确
public static void printTree(Node root) {
if (root == null) {
return;
}
System.out.print(root.val);
printTree(root.left);
printTree(root.right);
}
}
class Node {
char val;
Node left;
Node right;
public Node(char val) {
this.val = val;
}
}