03-树3 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

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer NN (\le 3030) which is the total number of nodes in a tree (and hence the nodes are numbered from 1 to NN). Then 2N2N 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

解:题意就是已知先序遍历和终须遍历,求出后序遍历的结果。
主要思路:

    1.根据入栈出栈顺序,建立先序遍历数组与中序遍历数组。

    2.取先序序列中的第一个元素,该元素为根结点

    3.根据根结点在中序序列中查找根结点的位置,从而得到该树左子树结点个数(L)与右子树的结点个数(R)

    4.在后序序列数组中,第0到第L个元素为左子树,第L+1到第L+R个元素为右子树,最后一个元素为根结点

    递归

我犯的错,讲post定义成vector老是会错,因为post并不是push_back操作,不明白??只好定义manLen了

C++代码:

#include <iostream>
#include <vector>
#include <stack>
#include <string>
using namespace std;
#define maxLen 30
vector<int> pre, in;
int post[maxLen];
int N;
int find_index(vector<int> v, int data){
	for(unsigned int i = 0; i < v.size(); i++){
		if(v[i] == data){
			return i;
		}
	}
	return -1;
}
void tree_traversals_again(int prehead, int inhead, int posthead, int len){
	if(len == 0)
		return;
	if(len == 1){
		post[posthead] = pre[prehead];
		return;
	}
	int root = pre[prehead];
	post[posthead + len - 1] = root;
	int index = find_index(in, root);
	int L = index - inhead;
	int R = len - L - 1;
	tree_traversals_again(prehead + 1, inhead, posthead, L);
	tree_traversals_again(prehead + L + 1, inhead + L + 1, posthead + L, R);
}
int main(){
	cin>>N;
	string str;
	int data;
	stack<int> sta;
	for(int i = 0; i < 2*N; i++){
		cin>>str;
		if(str == "Push"){
			cin>>data;
			pre.push_back(data);
			sta.push(data);
		}else{
			in.push_back(sta.top());
			sta.pop();
		}
	}
	tree_traversals_again(0,0,0,N);
	if(N){
		cout<<post[0];
		for(int i = 1; i < N; i++)
			cout<<' '<<post[i];
	}
	return 0;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值