给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列。这里假设键值都是互不相等的正整数。
输入格式:
输入第一行给出一个正整数N(≤30),是二叉树中结点的个数。第二行给出其后序遍历序列。第三行给出其中序遍历序列。数字间以空格分隔。
输出格式:
在一行中输出该树的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。
输入样例:
7
2 3 1 5 7 6 4
1 2 3 4 5 6 7
输出样例:
4 1 6 3 5 7 2
注意点:
解答:
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Scanner;
public class Main {
// 层次遍历序列
static ArrayList<Integer> levArray = new ArrayList<Integer>();
// 节点数
static int n;
public static void main(String[] args) {
// 中序遍历序列
ArrayList<Integer> midArray = new ArrayList<Integer>();
// 后序遍历序列
ArrayList<Integer> taiArray = new ArrayList<Integer>();
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
// 没有节点就退出
if (n >= 1) {
for (int i = 0; i < n; i++) {
taiArray.add(sc.nextInt());
}
for (int i = 0; i < n; i++) {
midArray.add(sc.nextInt());
}
// 二叉树的根
Tree root = new Tree();
root.data = taiArray.get(n - 1);
// 根在中序遍历序列的位置
int middle = midArray.indexOf(root.data);
// 对于中序遍历序列,根的左子树节点一定在根的左边,获得其集合
List<Integer> bLeft = midArray.subList(0, middle);
// 对于中序遍历序列,根的右子树节点一定在根的右边,获得其集合
List<Integer> bRight = midArray.subList(middle + 1, midArray.size());
// 根的左子树节点存在的集合(bLeft)中,其在后序遍历序列中最左边的节点的位置
int minIndex = 31, moveIndex;
for (int i = 0; i < bLeft.size(); i++) {
moveIndex = taiArray.indexOf(bLeft.get(i));
if (moveIndex < minIndex) {
minIndex = moveIndex;
}
}
List<Integer> aLeft;
// 如果没有找到
if (minIndex == 31) {
aLeft = new ArrayList<Integer>();
// 如果有找到
} else {
aLeft = taiArray.subList(minIndex, minIndex + bLeft.size());
}
// 同上
minIndex = 31;
for (int i = 0; i < bRight.size(); i++) {
moveIndex = taiArray.indexOf(bRight.get(i));
if (moveIndex < minIndex) {
minIndex = moveIndex;
}
}
List<Integer> aRight;
if (minIndex == 31) {
aRight = new ArrayList<Integer>();
} else {
aRight = taiArray.subList(minIndex, minIndex + bRight.size());
}
// 创建root的左子树
buildLeftTree(root, aLeft, bLeft);
// 创建root的右子树
buildRightTree(root, aRight, bRight);
// 层次遍历二叉树
ergodicPro(root);
// 输出遍历序列
for (int i = 0; i < levArray.size(); i++) {
System.out.print(levArray.get(i));
if (i != levArray.size() - 1) {
System.out.print(" ");
}
}
}
sc.close();
}
/**
* 层次遍历二叉树
* @param root 根节点
*/
private static void ergodicPro(Tree root) {
Queue<Tree> queue = new LinkedList<Tree>();
queue.add(root);
while (!queue.isEmpty()) {
Tree move = queue.poll();
levArray.add(move.data);
if (move.left != null) {
queue.add(move.left);
}
if (move.right != null) {
queue.add(move.right);
}
}
}
/**
* 创建root节点的左子树
* @param root 当前节点
* @param a 获得左子树节点的集合
* @param b 获得左子树节点的左右子树集合
*/
private static void buildLeftTree(Tree root, List<Integer> a, List<Integer> b) {
if (a.isEmpty() || b.isEmpty()) {
return;
}
root.left = new Tree();
int minIndex = 31, moveIndex;
for (int i = 0; i < b.size(); i++) {
moveIndex = a.indexOf(b.get(i));
if (moveIndex < minIndex) {
minIndex = moveIndex;
}
}
root.left.data = a.get(minIndex+b.size()-1);
List<Integer> aLeft = new ArrayList<Integer>();
List<Integer> aRight = new ArrayList<Integer>();
for (int i = 0; i < a.size(); i++) {
if (a.get(i) != root.left.data) {
aLeft.add(a.get(i));
aRight.add(a.get(i));
}
}
int middle = b.indexOf(root.left.data);
List<Integer> bLeft = new ArrayList<Integer>();
for (int i = 0; i < middle; i++) {
bLeft.add(b.get(i));
}
List<Integer> bRight = new ArrayList<Integer>();
for (int i = middle + 1; i < b.size(); i++) {
bRight.add(b.get(i));
}
buildLeftTree(root.left, aLeft, bLeft);
buildRightTree(root.left, aRight, bRight);
}
/**
* 创建root节点的右子树
* @param root 当前节点
* @param a 获得右子树节点的集合
* @param b 获得右子树节点的左右子树集合
*/
private static void buildRightTree(Tree root, List<Integer> a, List<Integer> b) {
if (a.isEmpty() || b.isEmpty()) {
return;
}
root.right = new Tree();
int minIndex = 31, moveIndex;
for (int i = 0; i < b.size(); i++) {
moveIndex = a.indexOf(b.get(i));
if (moveIndex < minIndex) {
minIndex = moveIndex;
}
}
root.right.data = a.get(minIndex+b.size() - 1);
List<Integer> aLeft = new ArrayList<Integer>();
List<Integer> aRight = new ArrayList<Integer>();
for (int i = 0; i < a.size(); i++) {
if (a.get(i) != root.right.data) {
aLeft.add(a.get(i));
aRight.add(a.get(i));
}
}
int middle = b.indexOf(root.right.data);
List<Integer> bLeft = new ArrayList<Integer>();
for (int i = 0; i < middle; i++) {
bLeft.add(b.get(i));
}
List<Integer> bRight = new ArrayList<Integer>();
for (int i = middle + 1; i < b.size(); i++) {
bRight.add(b.get(i));
}
buildLeftTree(root.right, aLeft, bLeft);
buildRightTree(root.right, aRight, bRight);
}
}
class Tree {
Tree left;
Tree right;
int data;
}