An inorder binary tree traversal can be implemented in a non-recursive way with a stack. For example, suppose that when a 6-node binary tree (with the keys numbered from 1 to 6) is traversed, the stack operations are: push(1); push(2); push(3); pop(); pop(); push(4); pop(); pop(); push(5); push(6); pop(); pop(). Then a unique binary tree (shown in Figure 1) can be generated from this sequence of operations. Your task is to give the postorder traversal sequence of this tree.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (≤30) which is the total number of nodes in a tree (and hence the nodes are numbered from 1 to N). Then 2N lines follow, each describes a stack operation in the format: "Push X" where X is the index of the node being pushed onto the stack; or "Pop" meaning to pop one node from the stack.
Output Specification:
For each test case, print the postorder traversal sequence of the corresponding tree in one line. A solution is guaranteed to exist. All the numbers must be separated by exactly one space, and there must be no extra space at the end of the line.
Sample Input:
6
Push 1
Push 2
Push 3
Pop
Pop
Push 4
Pop
Pop
Push 5
Push 6
Pop
Pop
Sample Output:
3 4 2 6 5 1
我的代码:C++(g++ 6.5.0)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
#define MaxSize 30
typedef struct Stack *PtrToStack;
struct Stack {
int top;
char stack[MaxSize];
};
char preOrder[MaxSize + 1]; //位置0不存节点
char inOrder[MaxSize + 1];
char postOrder[MaxSize + 1];
void BuildTree(PtrToStack S, char preOrder[], char inOrder[], char postOrder[], int N) {
char oprtn[5];
int i;
int j = 1;
int k = 1;
int node;
for (i = 1; i <= 2*N; i++) {
scanf("%s", oprtn);
if (strcmp(oprtn, "push") == 0) { //push
scanf("%d", &node);
preOrder[j++] = node;
S->stack[S->top++] = node;
}else { //pop
char temp = S->stack[--S->top];
inOrder[k++] = temp;
}
}
}
void Solve(char preOrder[], char inOrder[], char postOrder[], int Num, int preL, int inL, int postL) {
/*Num遍历时的节点总数 不是总的节点数, first先序遍历起始点, left与right是后序数组的区间*/
int i,index,lNum,rNum;
if (Num == 0) return;
if (Num==1) {
postOrder[postL] = preOrder[preL];
return;
}
postOrder[postL+Num-1] = preOrder[preL]; //先序遍历第一个节点为根节点,放在后序遍历区间最后一个位置
for (i = 0; i <= MaxSize; i++) { //找到根节点在中序遍历中的位置
if (inOrder[i] == preOrder[preL]) {
index = i;
break;
}
}
lNum = index - inL; //左子树节点个数
rNum = inL + Num - index - 1; //inL用于计算左右子树的节点数的
Solve(preOrder, inOrder, postOrder, lNum, preL+1, inL, postL);
Solve(preOrder, inOrder, postOrder, rNum, preL+lNum+1, index+1, postL + lNum);
}
int main()
{
int N;
bool first = true; //输出是否为第一个元素的标记
PtrToStack S = (PtrToStack)malloc(sizeof(struct Stack)); //记得free
S->top = 0;
scanf("%d", &N);
BuildTree(S, preOrder, inOrder, postOrder,N);
Solve(preOrder, inOrder, postOrder, N, 1, 1, 1);
for (int i = 1; i <= N;i++) {
if (first) {
printf("%d", postOrder[i]);
first = false;
}else {
printf(" %d", postOrder[i]);
}
}
return 0;
}