PAT 树的遍历 1086. Tree Traversals Again

1086. Tree Traversals Again (25)

时间限制
200 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

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

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.

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
//PAT 1086 .Tree Traversals Again  
#include <iostream>
#include <string>
using namespace std; 
int const MAX_NUM = 50;
int const SMAX = 50;  // 堆栈的大小
int Pre[MAX_NUM], In[MAX_NUM], Post[MAX_NUM]; //前序·中序·后序数组的大小

class cstack {                   //建立一个简单的堆栈 
private:
	int data[SMAX];              //堆栈的大小
	int sp;
public:
	cstack(){ sp = SMAX; }
	void push(int i){
		if (sp > 0) data[--sp] = i;
	}
	int pop(){
		if (sp < SMAX){
			return data[sp++];
		}
		return 0;
	}
	bool  IsEmpty() {
		return sp == SMAX;
	}
};

void solve(int PreL, int InL, int PostL,int N )  //PreL,InL,PostL 分别保存当前处理的前序数组,中序数组,后序数组的第一个元素的位置 ,N保存当前处理左子数或右子数元素的个数 
{
	int L, R, root, i;
	if (N == 0)  return;  
	if (N == 1)  
	    {
		Post[PostL] = Pre[PreL]; // 此时Pre[PreL]和In[InL]指向的是同一个叶节点
		return; 
       	}
    root = Pre[PreL]; 
	Post[PostL + N - 1] = root; // 取当前前序数组的第一个元素,将其赋值给后序数组的最后一个元素
	for ( i = 1; i <= N; i++)
	{
		if (In[InL + i - 1 ] == root)  break;  //找到前序数组的头结点在中序中的位置,从而划分左子树和右子树
	}
	L = i-1;  // 除去根节点后左子树元素个数
	R = N - i ;// 除去根节点右子树元素个数
// 递归处理左子树和右子树
	solve(PreL + 1, InL, PostL, L);
	solve(PreL + L + 1, InL + L + 1, PostL + L, R);
}

int main() {
	cstack stack; 
	string cs;
	int i , n , data ,PreL,InL;
	PreL = 0; 	InL = 0; 
    cin >> n; 
	for (int i = 1; i <=2 * n ; i++)
	{
		cin >> cs;
		if (cs == "Push")  {
			cin >> data;
			Pre[++PreL] = data;
			stack.push(data);
		}
		else 
		    if (cs == "Pop"){
			In[++InL] = stack.pop();
	     	}
			else { cout << "输入有误!!!!" << endl; }
	 }
	solve(1, 1, 1, n);
	for ( i = 1; i < n; i++)
	cout << Post[i] << " ";
	cout << Post[i];
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值