1. 程式人生 > 其它 >PAT (Advanced Level) Practice 1086 Tree Traversals Again (25 分) 凌宸1642

PAT (Advanced Level) Practice 1086 Tree Traversals Again (25 分) 凌宸1642

PAT (Advanced Level) Practice 1086 Tree Traversals Again (25 分) 凌宸1642

題目描述:

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.

譯:可以使用堆疊以非遞迴方式實現中序二叉樹遍歷。 例如,假設遍歷一棵6節點的二叉樹(鍵從1到6),棧操作為:push(1); push(2);push(3); pop() ; pop() ; push(4);pop() ; pop() ; push(5);push(6);pop() ; pop() ;。 然後可以從這個操作序列生成一個唯一的二叉樹(如圖 1 所示)。 你的任務是給出這棵樹的後序遍歷序列。


Input Specification (輸入說明):

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 Specification (輸出說明):

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

The Idea:

通過push X 的先後順序,我們可以很自然的想到push書序就是先序遍歷得到的序列,然後pop出棧的順序就是中序遍歷得到序列,有先序遍歷和中序遍歷,很自然的想到利用先序遍歷和中序遍歷重建二叉樹,然後對重建的二叉樹再進行後序遍歷即可。

The Codes:

#include<bits/stdc++.h>
using namespace std ;
struct node{
	int val ;
	node *l , *r ;
};
string s , s1 ;
node* root ;
int n , cnt = 0 , cnt2 = 0 , top = -1 , cnt3 = 0 ;
int pre[33] , in[33] , post[33];
node* create(int preL , int preR , int inL , int inR){
	if(preL > preR) return NULL;
	node* root = new node ;
	root->val = pre[preL] ;
	int k ; 
	for(k = inL ; k <= inR ; k ++){
		if(pre[preL] == in[k]) break ;
	}
	int numLeft = k - inL ;
	root -> l = create(preL + 1 , preL + numLeft , inL , k - 1) ;
	root -> r = create(preL + numLeft + 1 , preR , k + 1 , inR) ;
	return root ;
}
void postOrder(node *root){
	if(!root) return ;
	postOrder(root->l) ;
	postOrder(root->r) ;
	post[cnt3++] = root->val ;
}
int main(){
	cin >> n ;
	getline(cin , s) ; // 	吸收回車 
	stack<int> st ;
	for(int i = 0 ; i < 2 * n ; i ++){
		getline(cin , s) ;
		if(s.size() > 3){
			sscanf(s.substr(5 , s.size() - 5).c_str() , "%d" , &pre[cnt]) ; // 將字串轉為數字
			st.push(pre[cnt ++]) ;
		}else{
			in[cnt2 ++] = st.top() ;
			st.pop() ;
		}
	}
	root = create( 0 , n - 1 , 0 , n - 1) ;
	postOrder(root) ;
	for(int i = 0 ; i < n ; i ++)
		printf("%d%c" , post[i] , ((i == n -1)?'\n':' ')) ;
    return 0;
}