自行摸索的版本,部分代码可能有冗余
import java.io.*;
import java.util.*;
public class 二叉树遍历 {
static char[] inorder, layer;
static boolean[] flag;
static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));
public static void main(String[] args) throws IOException {
char[] temp = reader.readLine().trim().toCharArray();
ArrayDeque<Node> deque = new ArrayDeque<>(temp.length);
inorder = new char[temp.length+2];//输入的中序遍历顺序
layer = new char[temp.length+2];//输入的层序遍历顺序
//用于保存中序遍历顺序下某个值是否被遍历到,多申请两个是为了方便处理边界
flag = new boolean[temp.length+2];
//用于保存某个元素在中序遍历顺序中的位置
HashMap<Character, Integer> map = new HashMap<>(temp.length);
//读入数据
for (int i = 1; i <= temp.length; i++) {
inorder[i] = temp[i-1];
map.put(inorder[i],i);
}
temp = reader.readLine().trim().toCharArray();
for (int i = 1; i <= temp.length; i++) {
layer[i] = temp[i-1];
}
//初始化头结点并将其加入队列
Node head = new Node(layer[1]);
deque.add(head);
//此处将第一个与最后一个赋值为true用于确定边界,避免每次循环时重复判定是否越过了边界
flag[0] = flag[flag.length-1] = true;
flag[map.get(head.value)] = true;//将头结点变更为“已访问”
int index = 1;//用于保存当前访问到层序遍历中的哪一个值
while(!deque.isEmpty()){
Node node = deque.poll();
//如果当前节点在先序遍历的顺序里的左侧的值未被访问过,则说明当前节点有左孩子
if (!flag[map.get(node.value)-1]){
node.left = new Node(inorder[map.get(layer[++index])]);
deque.addLast(node.left);
flag[map.get(node.left.value)] = true;
}
//如果当前节点在先序遍历的顺序里的右侧的值未被访问过,则说明当前节点有右孩子
if (!flag[map.get(node.value)+1]){
node.right = new Node(inorder[map.get(layer[++index])]);
deque.addLast(node.right);
flag[map.get(node.right.value)] = true;
}
}
out(head);//用于递归输出先序遍历的结果
writer.flush();
}
static class Node{
char value;
Node left;
Node right;
public Node(char value) {
this.value = value;
left = null;
right = null;
}
}
public static void out(Node node) throws IOException {
writer.write(node.value+"");
if (node.left != null)
out(node.left);
if (node.right != null)
out(node.right);
}
}