hdu 1710 binary tree traversals 二叉树遍历

根据二叉树的前序遍历和中序遍历求后序遍历的题。

一开始的方法是根据前序遍历和中序遍历构建二叉树,再从二叉树开始后序遍历。事实证明我还是too young too naive,一开始还好好的,后来这递归被我越写越糟糕,都看不下去了,好不容易程序运行起来了,对了下答案也没问题,就交了上去,结果返回了RE……………………

好难过啊QAQ

于是去搜题解,发现有人说用结构构建树用了太多空间导致RE,但我觉得不应该啊QAQ,然后又找到个人也是构建了树再遍历的,不过他用的是指针,我直接开的两个整型来保存。(喵的现在这天气居然有人进来还开空调(╯‵□′)╯ノ┻━┻☆)可能就是这两个整型导致RE了?

总之先贴上错误的代码……


#include<cstdio>
#include<iostream>
#define MAXN 2005
#define Lc (id<<1)
#define Rc (Lc|1)
using namespace std;
int preorder[MAXN], inorder[MAXN], postorder[MAXN];
int tree[MAXN*4];
bool haveval[MAXN*4];
int orderpoint;
int search(int sx, int ex, int target){
	for(int i=sx;i<=ex;i++){
		if(inorder[i]==target)return i;
	}
}
int id;
void buildtree(int left, int mid, int right, int id){
	if(left==right){
		return ;
	}
	bool inleft=false;
	int leftu, rightu;
	tree[id]=inorder[mid];
	haveval[id]=true;
	if(left<=mid-1){
		orderpoint++;
		leftu=search(left, mid-1, preorder[orderpoint]);	
	}
	else leftu=left;
	if(left<=mid-1)
		buildtree(left, leftu, mid-1, Lc);
	if(mid!=leftu){
		tree[Lc]=inorder[leftu];
		haveval[Lc]=true;
		inleft=true;
	}
	if(mid+1<=right){
		orderpoint++;
		rightu=search(mid+1, right, preorder[orderpoint]);	
	}
	else rightu=right;
	if(mid+1<=right)
		buildtree(mid+1, rightu, right, Rc);	
	if(mid!=rightu){
		if(!inleft){
			tree[Lc]=inorder[rightu];haveval[Lc]=true;
		}
		else {
			tree[Rc]=inorder[rightu];haveval[Rc]=true;
		}
	}
}
void postsearch(int id){
	if(!haveval[id])return ;
	postorder[++orderpoint]=tree[id];
	postsearch(Rc);
	postsearch(Lc);
}
int main(){
	int n;
	while(cin>>n){
		memset(haveval, false, sizeof(haveval));
		for(int i=0;i<n;i++)
			scanf("%d", &preorder[i]);
		for(int i=0;i<n;i++){
			scanf("%d", &inorder[i]);
			if(inorder[i]==preorder[0])id=i;
		}
		orderpoint=0;
		buildtree(0, search(0, n-1, preorder[0]), n-1, 1);
		orderpoint=0;
		postsearch(1);
		for(int i=n;i>=2;i--)printf("%d ", postorder[i]);
		cout<<postorder[1]<<endl;
	}
	return 0;
}


总而言之暂时没想到哪里错了Orz……本渣还是研究下题解重写吧Orz……

*******************重写完毕************************

来个AC的代码

#include<cstdio>
#include<iostream>
using namespace std;
#define MAXN 1005
int preorder[MAXN], inorder[MAXN], postorder[MAXN];
int prept, postpt;
void search(int left, int right){
	if(left>right)return ;
	if(left==right){
		postorder[postpt++]=inorder[left];
		prept++;
		return ;
	}
	int inpt;
	for(inpt=left;inorder[inpt]!=preorder[prept];inpt++);
	prept++;
	search(left, inpt-1);
	search(inpt+1, right);
	postorder[postpt++]=inorder[inpt];
}
int main(){
	int n;
	while(cin>>n){
		for(int i=1;i<=n;i++)scanf("%d", &preorder[i]);
		for(int i=1;i<=n;i++)scanf("%d", &inorder[i]);
		prept=1;postpt=1;
		search(1, n);
		for(int i=1;i<n;i++)printf("%d ", postorder[i]);
		cout<<postorder[n]<<endl;
	}
	return 0;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值