天天看點

PAT A 1086. Tree Traversals Again

加粗樣式

【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++;
		}		
	}
}