重建二叉树

刚做了华为OJ练习,华为中给出了重建二叉树这道题目:

要求,给出前序和中序遍历,要求如果能够重建二叉树,就输出二叉树的后序遍历,否则的话输出"No"

重建二叉树一定要深刻理解二叉树的遍历(前、中、后)


#include<iostream>

using namespace std;

int n;
int a[1005]; //记录前序遍历的结果
int b[1005]; //记录中序遍历的结果
int c[1005][1005];  //用于记录中序遍历中,c[i][j]表示i是在j的左子树还是右子树

int L[1005]; //记录后序遍历的结果
int pL=0;//当前L元素位置

int F[1005]; //记录重建二叉树后前序遍历的结果
int pf=0;//当前F元素位置

int Z[1005]; //记录重建二叉树中序遍历的结果
int pz=0;//当前Z元素位置


struct node{
	
	//left表示左子树、right表示右子树
	node *left,*right;
	
	int value;
};

node *head;//表示头,根节点

//这是用来求L的
void printL(node *f){
	
	F[pf++]=f->value; //在左右递归之前记录value,这是前序遍历,父、左、右

	if(f->left!=NULL) printL(f->left);  //向左子树递归
	
	Z[pz++]= f->value;//左、中、右,先遍历左子树,直接递归到叶节点,然后回溯记录,中序遍历

	if(f->right!=NULL) printL(f->right);//向右子树递归
	L[pL++]=f->value;//左、右、中,先遍历左子树,后右子树,后父节点,后序遍历
}

int main(){

	while(cin>>n){

		for(int i=0;i<n;i++) cin>>a[i]; 


		for(int i=0;i<n;i++) {	
			cin>>b[i];
			for(int j=0;j<i;j++){

			c[b[j]][b[i]]=1;  //b[j]节点在b[i]节点之前,即在其左边
			c[b[i]][b[j]]=-1; 
			
			}
		}
		head = (struct node *)malloc(sizeof(node));

		head->value=a[0];//头结点
		head->left=NULL;
		head->right=NULL;
	
		for(int i=1;i<n;i++){
			//以前序遍历为基础,中序遍历为控制条件,重建二叉树
			node *fn= (struct node *)malloc(sizeof(node));
			fn->left=NULL;
			fn->right=NULL;

			fn->value=a[i];
			node *h=head;
			node *ph=head;
			int flag=0;
			while(h!=NULL){
				ph=h;
				if(c[fn->value][h->value] == 1) //向左递归	
				{
							h=h->left;
							if(h==NULL) ph->left=fn; //递归到叶节点,结束,添加fn		
				}

				else if(c[fn->value][h->value] == -1)//向右递归
				{
					h=h->right;
					if(h==NULL) ph->right=fn;//递归到叶节点,结束,添加fn		
				}
			}
			
		
		}
		pL=0;
		pf=0;
		pz=0;
		printL(head);//求重建后的二叉树,前、中、后
		int flag=0;

		//判断重建后的二叉树,前后遍历顺序是否正确,错误,则无法重建二叉树
		for(int i=0;i<n;i++){
			if(a[i]!=F[i]) {
				flag=1;
				break;
			}
			if(b[i]!=Z[i]){
				flag=1;
				break;
			}
		}
		if(flag==0){
		for(int i=0;i<n;i++)
			cout<<L[i]<<" ";
		cout<<endl;
		//cout<<L[n-1]<<endl;
	
		}
		else cout<<"No"<<endl;
	}
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值