加粗样式
【PAT】1086. Tree Traversals Again (25)
标题题目描述
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.
Figure 1
翻译:一个二叉树中序遍历可以用一个栈非递归实现。举个例子,假设有一棵6节点的二叉树(键值从1到6)。这个栈的操作为:push(1); push(2); push(3); pop(); pop(); push(4); pop(); pop(); push(5); push(6); pop(); pop()。根据这些操作队列可以构建一棵特定的二叉树(如图一所示)。你的任务是给出构建的二叉树的后序遍历。
INTUT FORMAT
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.
翻译:每个输入文件包含一组测试数据。对于每组输入数据,第一行包括两个正整数N(<=30),代表一棵树的节点总数(并且假设树的节点为1到N)。接着2N行,每个按照以下格式描述一个栈操作:“Push X”,X为压入栈的节点标号,“Pop”代表出栈的节点编号。
OUTPUT FORMAT
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
思路
入栈顺序是按二叉树先序序列来的
出栈顺序是按二叉树中序序列来的
题目是说给你一个二叉树先序 中序序列生成这个二叉树,并按后序输出;
#include<stdio.h>
#include<string.h>
typedef struct node{
int data;
int left;
int right;
}tnode;
// 按前序 中序 建立二叉树
int pre_in_buildtree(tnode pre[],int p1,int p2,tnode in[],int q1,int q2);
//逆序输出
int Flag=0; //控制空格输出的标志
void postorder(tnode T[],int p);
int main(){
// freopen("test.txt", "r", stdin);
int N;
scanf("%d",&N);
int s[N],top=0; //建立栈
tnode pre[N+1]; //静态存储前序数组 下标1开始
int a=1;
tnode T[N+1];//静态存储中序数组,下标1开始,
int b=1; //其指针按链式建立二叉树
char cs[5]; //存储字符串
int x;
while(b<=N){
scanf("%s",&cs);
if(cs[1]=='u'){
//输入Push 则寨读入一个数组,入栈,前序数组记录
scanf("%d",&x);
s[top++]=x;
pre[a++].data=x;
}else if(cs[1]=='o'){
//输入Pop 则数据出栈 中序数组记录
x=s[--top];
T[b++].data=x;
}else{
printf("ERROR\n");
return -1;
}
}
// 按前序 中序 建立二叉树
int post=pre_in_buildtree(pre,1,N,T,1,N);
//逆序输出
Flag=0; //控制空格输出的标志
postorder(T,post);
}
int pre_in_buildtree(tnode pre[],int p1,int p2,tnode in[],int q1,int q2){
//前序数组 pre,前序起始及终点序号 p1,p2; 中序数组 in,中序起始及终点序号 q1,q2
int i;
int il=-1,ir=-1;//结点孩子指针初始化为 -1
//寻找根节点在中序数组位置
for(i=q1;i<q2;i++){
if(in[i].data==pre[p1].data) break;
}
//根节点将中序数组分为两部分
int llen=i-q1; //左部分长度
int rlen=q2-i;//右部分长度
//嵌套调用
if(llen) {
il=pre_in_buildtree(pre,p1+1,p1+llen,in,q1,q1+llen-1);
}
if(rlen){
ir=pre_in_buildtree(pre,p2-rlen+1,p2,in,q2-rlen+1,q2);
}
in[i].left=il;
in[i].right=ir;
return i;
}
void postorder(tnode T[],int p){
if(p>0){
if(T[p].left>0){
postorder(T,T[p].left);
}
if(T[p].right>0){
postorder(T,T[p].right);
}
if(Flag) printf(" %d",T[p].data);
else {
printf("%d",T[p].data);
Flag++;
}
}
}