题目链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805380754817024
题目描述
可以以非递归方式使用堆栈来实现有序二叉树遍历。例如,假设遍历6节点的二叉树(键的编号从1到6),则堆栈操作为:push(1); push(2); push(3); pop(); pop(); push(4); pop(); pop(); push(5); push(6); pop(); pop()。然后可以从此操作序列中生成唯一的二叉树(如图1所示)。您的任务是给出此树的后置遍历序列。
输入
每个输入文件包含一个测试用例。对于每种情况,第一行都包含一个正整数N(≤ 3 0),它是节点的树中的总数量(并且因此节点编号从1到N)。然后随后有2条N行,每行以以下格式描述堆栈操作:“ Push X”,其中X是被压入堆栈的节点的索引;或“ Pop”表示从堆栈中弹出一个节点。
输出
对于每个测试用例,在一行中打印相应树的后遍历序列。保证存在解决方案。所有数字必须完全由一个空格分隔,并且行尾不得有多余的空格。
样例输入
6
Push 1
Push 2
Push 3
Pop
Pop
Push 4
Pop
Pop
Push 5
Push 6
Pop
Pop
样例输出
3 4 2 6 5 1
代码
#include<cstdio>
#include<stack>
#include<cstring>
using namespace std;
const int maxn = 40;
struct node{
int data;
node* lchild;
node* rchild;
};
int pre[maxn],in[maxn],post[maxn];
int n;
node* create(int preL,int preR,int inL,int inR){
if(preL > preR) return NULL;
node *root = new node;
root->data = pre[preL];
int k;
for(k = inL; k <= inR; k++){
if(in[k] == pre[preL]) break; //输出数值不对要检查判断数值问题
}
int numleft = k - inL;
root->lchild = create(preL+1,preL+numleft,inL,k-1);
root->rchild = create(preL+numleft+1,preR,k+1,inR);
return root;
}
int num = 0;
void postorder(node* root){
if(root == NULL) return;
postorder(root->lchild);
postorder(root->rchild);
printf("%d",root->data);
num++;
if(num < n)printf(" ");
}
int main(){
scanf("%d",&n);
stack<int> st;
int x,preIndex = 0,inIndex = 0;
char str[10];
for(int i = 0; i < 2*n; i++){
scanf("%s",str);
if(strcmp(str,"Push") == 0){
scanf("%d",&x);
st.push(x);
pre[preIndex++] = x;
}else{
in[inIndex++] = st.top();
st.pop();
}
}
node* root = create(0,n-1,0,n-1);
postorder(root);
return 0;
}