PAT 甲级 A1086 Tree Traversals Again

题意:用栈出入栈(push,pop)来确定唯一的二叉树,已知其中一个序列是中序遍历,求后序遍历。

分析:
由题意知,按一定的进出栈的顺序,可以确定两个序列,因此,应该是进栈是一个遍历序列,出栈也是一个遍历序列,因为题目给出,"An inorder binary tree traversal",因此,其中有一个序列应该是中序遍历序列,假设入栈是先序遍历序列,出栈是中序序列,则确定唯一二叉树,再进行后续遍历进行验证,从而可得出入栈是先序遍历,出栈是中序遍历。 

该树如图所示:

思路:套模板;

代码:

#include<iostream>
#include<stack>
using namespace std;
const int maxn=50;
int n;
int in[maxn],pre[maxn];
int preindex=0,inindex=0;
struct node{
	int data;
	node* lchild;
	node* rchild;
};
node* create(int preL,int preR,int inL,int inR){
	if(preL>preR)return NULL;
	node* root=new node;
	root->data=pre[preL];
	int k=inL;
	for(k=inL;k<=inR;k++){
		if(in[k]==root->data)break;
	}
	int leftnum=k-inL;
	root->lchild=create(preL+1,preL+leftnum,inL,k-1);
	root->rchild=create(preL+leftnum+1,preR,k+1,inR);
	return root;
}
int m=0;
void postorder(node* root){//后序遍历--左右根; 
	if(root==NULL)return ;
	postorder(root->lchild);
	postorder(root->rchild);
	printf("%d",root->data);
	m++;
	if(m<n)printf(" ");
}
int main( ){
	scanf("%d",&n);//结点个数; 
	getchar( );
	stack<int > s;
	string str;
	int num;
	for(int i=0;i<2*n;i++){//出栈,所以是2n 
		cin>>str;//不能用scanf输入string类型,如果用printf输出string类型要用.c_string转换; 
		if(str=="Push"){
			scanf("%d",&num);			
			s.push(num);
			pre[preindex++]=num;
		}else {
			in[inindex++]=s.top();//栈取出顶部元素用的是top; 
			s.pop( );
		}
	}
	node* root=create(0,n-1,0,n-1);
	postorder(root);
	return 0;
}


注意:不要用scanf输入string类型,想用printf输出string类型要用str.c_str()函数。

#include<iostream>
#include<stack>
using namespace std;
struct node {
	int data;
	node* lchild;
	node* rchild;
};

stack<int > st;
const int Maxn = 10010;
int pre[Maxn];
int in[Maxn];
string str;
int num1 = 1, num2 = 1;//从下标为1开始存储; 
int num;
int n;

node* create(int preL, int preR, int inL, int inR) {
	if(preL > preR)
		return NULL;
	node* root = new node;
	root->data = pre[preL];
	int k;
	for(k = inL; k <= inR; k++) {
		if(in[k] == root->data)
			break;
	}
	int Lnum = k - inL;
	root->lchild = create(preL + 1, preL + Lnum, inL, k - 1);
	root->rchild = create(preL + Lnum + 1, preR, k + 1, inR);
	return root;
}

int cnt = 0;
void postorder(node* root) {
	if(root == NULL)
		return ;
	postorder(root->lchild);
	postorder(root->rchild);
	cout << root->data;
	if(++cnt < n)
		cout << " ";
}
int main() {
	cin >> n;
	for(int i = 1; i <= n * 2; i++) {
		cin >> str;
		if(str == "Push") {
			cin >> num;
			st.push(num);
			pre[num1++] = num;
		} else {
			in[num2++] = st.top();
			st.pop();
		}
	}
	node* root = create(1, n, 1, n);
	postorder(root);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值