之前的解法是:得到前序和中序遍历,建立二叉树,然后输出后序遍历
后来经过陈越老师的讲解才知道,其实没有必要去建立二叉树,知道前序和中序的情况下,可以直接利用递归求得后续遍历
Java代码如下:
import java.util.Scanner;
import java.util.Stack;
/**
* Tree Traversals Again 之前已经写了一篇博客,但后来发现那并不是最优的解法
* 原来知道树的前序中序遍历以后并不需要建树,可以通过递归直接写出后续遍历
*
* @author Jacob
*
*/
public class TreeTraversalsAgain {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int NODE_NUM = sc.nextInt();
int[] preOrder = new int[NODE_NUM];
int[] inOrder = new int[NODE_NUM];
int preCount = 0;
int inCount = 0;
Stack<Integer> stack = new Stack<Integer>();
int tmp;
String operate;// 用来保存push或者pop
// 通过堆栈操作序列得到前序遍历和中序遍历
// 注意:字符串比较不能用“==”,要用equals()
for (int i = 0; i < NODE_NUM * 2; i++) {
operate = sc.next();
if (operate.equals("Push")) {
tmp = sc.nextInt();
stack.push(tmp);
preOrder[preCount] = tmp;
preCount++;
} else if (operate.equals("Pop")) {
inOrder[inCount] = stack.pop();
inCount++;
}
}
//
int[] postOrder = new int[NODE_NUM];
solve(preOrder, inOrder, postOrder, 0, 0, 0, NODE_NUM);
for (int i = 0; i < NODE_NUM; i++) {
System.out.print(postOrder[i]);
if(i!=NODE_NUM-1){
System.out.print(" ");
}
}
sc.close();
}
public static void solve(int[] preOrder, int[] inOrder, int[] postOrder, int preLeft, int inLeft, int postLeft,
int num) {
if (num == 0) {
}
if (num == 1)
postOrder[postLeft] = preOrder[preLeft];
if (num > 1) {
int findNum = 0; // 存储中间节点的下标
for (int i = inLeft; i < inLeft + num; i++) {
if (preOrder[preLeft] == inOrder[i]) {
findNum = i;
break;
}
}
postOrder[postLeft + num - 1] = preOrder[preLeft];
int leftNum = findNum - inLeft;
int rightNum = num - leftNum - 1;
solve(preOrder, inOrder, postOrder, preLeft + 1, inLeft, postLeft, leftNum);
solve(preOrder, inOrder, postOrder, preLeft + leftNum + 1, inLeft + leftNum + 1, postLeft + leftNum,
rightNum);
}
}
}
/**
* 树节点类
*
*/
class Node {
int value;
Node left;
Node right;
Node(int value) {
this.value = value;
left = null;
right = null;
}
}