问题链接: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所示)。你的任务是给出这个树的后序遍历序列。
题意:用栈来模拟一棵二叉树的先序和中序遍历过程,求这棵二叉树的后序遍历。
思路:由题意,每次访问一个新结点时就把它入栈,这个过程和先序序列总是先访问根节点的性质是相同的,因此Push的次序就是先序遍历序列中元素的顺序;Pop则是按左子树、根节点、右子树的顺序进行的(题目第一句话也给出是中序遍历),因此Pop的次序是中序遍历序列中元素的顺序。
#include<cstdio>
#include<iostream>
#include<stack>
using namespace std;
int pre[30], in[30];//存储先序,中序遍历序列
int n;//树的结点数
struct node{
int data;
struct node *lchild, *rchild;
};
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(pre[preL] == in[k])
break;
int left = k - inL;
root -> lchild = create(preL + 1, preL + left, inL, k - 1);
root -> rchild = create(preL + left + 1, preR, k + 1, inR);
return root;
}
int num = 0;
void postorder(node *T){
if(T == NULL)
return;
postorder(T -> lchild);
postorder(T -> rchild);
cout << T -> data;
num ++;
if(num < n)
cout << " ";
}
int main(){
cin >> n;//输入树结点个数
string A;
int x;
int preK = 0, inK = 0;
stack<int> st;
for(int i = 0; i < 2*n; i++){
cin >> A;
if(A == "Push"){
cin >> x;
pre[preK++] = x;
st.push(x);
}
else if(A == "Pop"){
x = st.top();
in[inK++] = x;
st.pop();
}
}
node *root = create(0, n-1, 0, n-1);
postorder(root);
return 0;
}