加粗樣式
【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++;
}
}
}