PAT 1020 Tree Traversals题解和扩展

题目大意:给出一个序列的中序和后序,输出该序列的层次遍历序列。
解决方法:重建二叉树+层次遍历

/*根据二叉树的后序和中序,重建二叉树,输出层次序列*/

#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<cstdlib>

using namespace std;

vector<int>in,post;
int pos;
int N;

struct Bitree{
	int data;
	Bitree *lson;
	Bitree *rson;
};

//重建二叉树 
Bitree* rec(int l,int r){
	if(l>=r)return NULL;	
	int root=post[pos--];
	int m=distance(in.begin(),find(in.begin(),in.end(),root));	
	Bitree *t;
	t=(Bitree *)malloc(sizeof(Bitree));
	t->data=root;	
	t->rson=rec(m+1,r);	
	t->lson=rec(l,m);	
	return t;
}

//层次遍历 
//由于格式要求,需要先保存结果,而不直接进行输出 
void bfs(Bitree *b){
	vector<int>res;
	queue<Bitree *>q;
	q.push(b);
	while(!q.empty()){
		Bitree* tmp=q.front();
		q.pop();
		res.push_back(tmp->data);
		if(tmp->lson!=NULL){
			q.push(tmp->lson);
		}
		if(tmp->rson!=NULL){
			q.push(tmp->rson);
		}
	}
	
	for(int i=0;i<res.size();i++){
		cout<<res[i];
		if(i!=res.size()-1)cout<<" ";	
	}
}

int main(){
	cin>>N;
	pos=N-1;
	for(int i=0;i<N;i++){
		int a;
		cin>>a;
		post.push_back(a);
	}
	
	for(int i=0;i<N;i++){
		int a;
		cin>>a;
		in.push_back(a);
	}
	
	Bitree *bt;
	
	bt=rec(0,N);
	
	//输出层次遍历 
	bfs(bt);
	
	return 0;
}


该类相似问题:
1.在该问题的基础上,输出前序序列。这时可以对重建后的二叉树进行先序遍历,便可得到。
2.给出二叉树的先序和中序,给出后序或层次遍历。


/*根据二叉树的先序和中序,重建二叉树,输出后序和层次序列*/

#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<cstdlib>

using namespace std;

vector<int>pre,in,post;
int pos;
int N;

struct Bitree{
	int data;
	Bitree *lson;
	Bitree *rson;
};

Bitree* rec(int l,int r){
	if(l>=r)return NULL;	
	int root=pre[pos++];
	int m=distance(in.begin(),find(in.begin(),in.end(),root));	
	cout<<"m:"<<m<<endl;
	Bitree *t;
	t=(Bitree *)malloc(sizeof(Bitree));
	t->data=root;	
	t->lson=rec(l,m);
	t->rson=rec(m+1,r);	
	post.push_back(root);
	return t;
}

void bfs(Bitree *b){
	queue<Bitree *>q;
	q.push(b);
	while(!q.empty()){
		Bitree* tmp=q.front();
		q.pop();
		cout<<tmp->data<<" ";
		if(tmp->lson!=NULL){
			q.push(tmp->lson);
		}
		if(tmp->rson!=NULL){
			q.push(tmp->rson);
		}
	}
}

int main(){
	cin>>N;
	pos=0;
	for(int i=0;i<N;i++){
		int a;
		cin>>a;
		pre.push_back(a);
	}
	
	for(int i=0;i<N;i++){
		int a;
		cin>>a;
		in.push_back(a);
	}
	
	Bitree *bt;
	
	bt=rec(0,N);
	
	//输出后序 
	for(int i=0;i<pre.size();i++){
		cout<<post[i]<<" ";
	}
	cout<<endl;
	
	//输出层次遍历 
	bfs(bt);
	return 0;
}

心得:
问题1:给出先序和中序求后序
问题2:给出后序和中序求先序

首先三种序列的顺序为:
先序:根左右
中序:左根右
后序:左右根

两种问题的解决思路的区别:

1.重建二叉树时存在不同
问题1:对先序序列从头开始遍历,并寻找该结点在中序序列中的对应位置,然后重建左子树、右子树
问题2:对后序序列从尾开始遍历,并并寻找该结点在中序序列中的对应位置,然后重建右子树、左子树
两者之间的差异是由于先序序列和后序序列的差异。

2.问题1获取结果序列时,可以在重建二叉树的过程中使用vector进行保存,但问题2不可以,因为先重建的右子树。两者都可以先重建二叉树,再进行遍历的方法得到结果序列。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值