7-10 还原二叉树 (100分) ---中后序建立二叉树的链表和非链表做法

给出一颗二叉树的中序遍历和后序遍历,请你实现以下两个需求:

(1)请你输出这颗二叉树的层序遍历。

(2)请你输出这颗二叉树的树高。

输入格式:

第一行包含一个整数N(N<=1000)。二叉树的节点将从1到N编号。

第二行包含N个节点编号,表示这颗二叉树的中序遍历。

第三行包含N个节点编号,表示这颗二叉树的后序遍历。

输出格式:

第一行输出二叉树的层序遍历,节点编号之间用空格分隔,末尾没有多余空格。

第二行输出一个整数,代表二叉树的树高。

题目不保证输入的序列合法,如果遇到不合法的情况,请在一行中输出"ERROR",直接退出程序。

输入样例:

在这里给出一组输入。例如:

6
6 5 4 3 2 1 
5 6 2 3 1 4 

输出样例:

在这里给出相应的输出。例如:

4 6 1 5 3 2
4

输入样例:

在这里给出一组输入。例如:

3
2 1 3
3 2 1

输出样例:

在这里给出相应的输出。例如:

ERROR

 

 

 


题解

思路得到了一下这位的启发,首先表示感谢。

https://blog.csdn.net/qq_44378358/article/details/99879072

 

其实最开始我是用单纯的结构和C++的STL来做的,但一直有段错误。我执行着案例没有问题,但提交就会有段错误的点。

改了好长时间也不对,搁置一段时间后,决定从网上学习一下。

网上都是链表做法,遂学习了一下。

 

没太多要讲解的,就是根据中序和后序建立二叉树而已,简单注释即可。

 

ac代码---链表

#include<bits/stdc++.h>		    //建立一棵二叉树 
using namespace std;

int N,in[2000],back[2000];            //N 中序 后序
int flag=1;                           //判断有问题
int height=-1;	                      //深度
 

typedef struct BitNode{		        //二叉链表结点结构 
	int data;		        //结点数据 
	struct BitNode *lchild,*rchild;		    //左右孩子指针 
}BitNode,* BitTree;		        //并列改名,定义结点用BitNode,定义结点指针用BitTree 


BitTree CreateTree(int inl,int inr,int backl,int backr)	    //建立二叉树函数 
{
	if(inl==inr)	                //只有一个元素 
	{
		if(back[backl]!=in[inl])
		{
			flag=0;            //判断错误
			return NULL;
		}
	}
       

	if(backl>backr)	return NULL;        
	BitTree a = new BitNode;        //分配空间(C++用的是new)
	a->data = back[backr];
	
	int m;
	for(int i=inl;i<=inr;i++)	//找根的位置下标 
	{
		if(in[i]==back[backr])
		{
			m = i;
			break;
		}
	}							
								//m是中序中的位置,用于后序要慎重! 
	a->lchild = CreateTree(inl,m-1,backl,backl+m-inl-1);	//最后位置不能写back+m-1,应该相对backl控制数量 
	a->rchild = CreateTree(m+1,inr,backl+m-inl,backr-1);    //这里写不好就会一直递归,段错误 
	return a;
}

void get_height(BitTree a,int ceng)        //求深度函数
{
	if(a==NULL)	
	{
		if(ceng>height)	height = ceng;
		return;
	}
	get_height(a->lchild,ceng+1);
	get_height(a->rchild,ceng+1);
	ceng++;
}

queue<BitTree>q;		//结构指针队列 
vector<int>vec;			//开个不定长数组 


int main()
{
	cin>>N;
	for(int i=0;i<=N-1;i++)
		cin>>in[i];
	for(int i=0;i<=N-1;i++)
		cin>>back[i];
	
	BitTree root = CreateTree(0,N-1,0,N-1);	
	
	if(flag==0)
	{
		cout<<"ERROR\n";
		return 0;
	}
	
	//层序遍历
	q.push(root);
	while(q.size())
	{
		BitTree a = q.front();
		vec.push_back(a->data);		//读入 
		
		if(a->lchild!=NULL)	q.push(a->lchild);
		if(a->rchild!=NULL)	q.push(a->rchild);
		q.pop();
	}
	
	for(int i=0;i<=vec.size()-1;i++)
	{
		if(i==0)	cout<<vec[i];
		else		cout<<" "<<vec[i];
	}
	cout<<endl;
	
	get_height(root,0);
	
	cout<<height<<endl;
	return 0;
}

 

 

ac代码---非链表

#include<bits/stdc++.h>
using namespace std;

int N,in[2000],back[2000];            //N 中序 后序
int flag=1;                           //判断有问题
int height=-1;	                      //深度

struct node{
	int l,r;
}p[2000];

int tree(int inl,int inr,int backl,int backr)	//a 中序  b 后序 
{
	if(inl==inr)	                //只有一个元素 
	{
		if(back[backl]!=in[inl])
		{
			flag=0;            //判断错误
			return 0;
		}
	}
	
	if(backl>backr)	return 0;
	int item = back[backr];
	int m;
	
	for(int i=inl;i<=inr;i++)
	{
		if(in[i]==item)
		{
			m = i;
			break;
		}
	}
	
	p[item].l = tree(inl,m-1,backl,backl+m-inl-1);
	p[item].r = tree(m+1,inr,backl+m-inl,backr-1);
	
	return item;
}

void get_height(int root,int ceng)        //求深度函数
{
	if(root==0)	
	{
		if(ceng>height)	height = ceng;
		return;
	}
	get_height(p[root].l,ceng+1);
	get_height(p[root].r,ceng+1);
	ceng++;
}

queue<int>q;
vector<int>vec;

int main()
{
	cin>>N;
	for(int i=0;i<=N-1;i++)
		cin>>in[i];
	for(int i=0;i<=N-1;i++)
		cin>>back[i];
	
	
	for(int i=0;i<=N-1;i++)	//初始化 
	{
		p[i].l = 0;
		p[i].r = 0;
	}
	
	int root = tree(0,N-1,0,N-1);
	
	if(flag==0)
	{
		cout<<"ERROR\n";
		return 0;
	}
	
	q.push(root);
	while(q.size())
	{
		if(p[q.front()].l!=0)	q.push(p[q.front()].l);
		if(p[q.front()].r!=0)	q.push(p[q.front()].r);
		vec.push_back(q.front());
		q.pop();
	}
	
	for(int i=0;i<=vec.size()-1;i++)
	{
		if(i==0)	cout<<vec[i];
		else		cout<<" "<<vec[i];
	}
	
	cout<<endl;
	
	get_height(root,0);
	
	cout<<height<<endl;
	
	return 0;
}

 

二者思路完全一致,就是前者用了链表和指针,后者只用了单纯的结构。要是比赛,还是写后者好些。链表细节有点多,还要分配空间,太麻烦了。

 

 


如果只是想看正确结果,看前面即可。

接下来放上的,是我的最初解,就是案例ok,但是一直提示段错误的代码。

 

错误代码

#include<bits/stdc++.h>
using namespace std;

int height=-1;

struct node{
	int l,r;
}p[2000];

int tree(string a,string b)	//a 中序  b 后序 
{
	if(a.size()==1&&b.size()==1)
	{
		return a[0];
	}
	if(a.size()==0 || b.size()==0)
	{
		return 0;
	}
	char ch = b[b.size()-1];
	int m = a.find(ch);
	p[ch].l = tree(a.substr(0,m),b.substr(0,m));
	p[ch].r = tree(a.substr(m+1),b.substr(m,a.size()-m-1));
	
	return ch;
}

void get_height(int root,int ceng)        //求深度函数
{
	if(root==0)	
	{
		if(ceng>height)	height = ceng;
		return;
	}
	get_height(p[root].l,ceng+1);
	get_height(p[root].r,ceng+1);
	ceng++;
}

queue<int>q;

int main()
{
	int N;
	cin>>N;
	
	string a="",b="";
	char ch;
	for(int i=1;i<=N;i++)
	{
		cin>>ch;
		a+=ch;
	}
	for(int i=1;i<=N;i++)
	{
		cin>>ch;
		b+=ch;
	}
	
	for(int i=1;i<=N;i++)
	{
		p[i].l = 0;
		p[i].r = 0;
	}
	
	int root = tree(a,b);
	q.push(root);
	
	int flag=1;
	while(q.size())
	{
		if(p[q.front()].l!=0)	q.push(p[q.front()].l);
		if(p[q.front()].r!=0)	q.push(p[q.front()].r);
		if(flag==1)
		{
			cout<<q.front()-'0';
			flag=0;
		}
		else
			cout<<" "<<q.front()-'0';
		
		q.pop();
	}
	cout<<endl;
	
	get_height(root,0);
	
	cout<<height<<endl;
	
	return 0;
}

 

用上STL的find和substr显然降低了思考量,但是没有过(lll¬ω¬)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值