原题: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.
题意:给定含n个节点的树,执行Push , Pop 语句后得到的结果为树的中序。另外Push的数字顺序即为树的前序(普通树就是“根左右”顺序建立的)。由此得到树的前序,中序遍历 。
eg(数据见下图):前序结果:1 2 3 4 5 6; 中序结果:3 2 4 1 6 5。
求解后序思路:前序确定根节点,然后到中序数组中找到根节点的位置,至此在中序中可以划分左右子树,递归执行。完成对后序遍历。注意:因为划分时是左右根顺序,刚好符合后序遍历顺序。因此可以用一个vector数组来记录后序元素。
代码:
/**
@PAT-Tree Traversals Again
*/
#include<bits/stdc++.h>
using namespace std;
vector<int> pre,in,post;
void postorder(int root, int start, int end) {
if (start>end) return;
int i = start;
while (i<end&&in[i] != pre[root]) i++; //找到根节点在中序中的位置
postorder(root+1,start,i-1); //左子树
/**
*root+1:根节点的位置(在前序中体现),
*start:左子树元素的起始位置(在中序数组中体现),
*i-1:左子树元素的结束位置(在中序数组中体现)
*/
postorder(root+1+i-start,i+1,end); //右子树
/**
*root+1+i-start:
root+1为左子树的根节点位置,
i-start:左右子树根节点位置(在中序数组中体现)的差值(差值等于上面找根节点所移动距离)
*/
post.push_back(pre[root]); //压入根节点
}
int main() {
int n;
scanf("%d",&n);
stack<int> s;
for(int i = 0;i<2*n;i++){
char str[10];
scanf("%s",str);
if(strlen(str)==4) {
int num;
scanf("%d",&num);
pre.push_back(num);
s.push(num); //压入栈
} else {
in.push_back(s.top());
s.pop();
}
}
postorder(0,0,n-1);
printf("%d", post[0]);
for (int i = 1; i < n; i++)
printf(" %d",post[i]);
return 0;
}