1151 LCA in a Binary Tree(30 分)

要求:给定先序和中序,确定一棵树,然后给定两个key值,在树中查找离两个结点最小路径的祖先结点,并按要求输出。

方法:由先序和中序先建立树,并存每个节点的父亲结点和深度。树不一定需要链表存储,可以用数组。

考场上和平时写代码还是不一样。

代码:

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

int pre[10000],in[10000];
map<int,pair<int,int> >no;  //因为key的范围为int,用数组存会内存超限
map<int,bool>flag;

void totree(int inL,int inR,int preL,int pa,int le) //建树和存父亲结点和深度
{
	if(inL>inR)return ;
	int i=inL;
	no[pre[preL]]=make_pair(le,pa);
	while(in[i]!=pre[preL])++i;
	totree(inL,i-1,preL+1,pre[preL],le+1);
	totree(i+1,inR,preL+i-inL+1,pre[preL],le+1);
}

int main()
{
	//freopen("test.txt","r",stdin);
	int N,M,i;
	scanf("%d %d",&M,&N);
	for(i=0;i<N;++i)scanf("%d",&in[i]);
	for(i=0;i<N;++i)scanf("%d",&pre[i]),flag[pre[i]]=1;
    totree(0,N-1,0,-1,0);
	while(M--){
    	int a,b;
    	scanf("%d %d",&a,&b);
    	if(!flag[a]&&!flag[b])printf("ERROR: %d and %d are not found.\n",a,b);
    	else if(!flag[a]||!flag[b])printf("ERROR: %d is not found.\n",flag[a]?b:a);
    	else{
    		if(a==b)printf("%d is an ancestor of %d.\n",a,b); //相等时是按这种方式,不是另外一种
    		else if(no[a].second==b||no[b].second==a)printf("%d is an ancestor of %d.\n",no[a].second==b?b:a,no[a].second==b?a:b);
    		else{
    		  int x=a,y=b;
    			//printf("LCA of %d and %d is ",a,b);
    			if(no[a].first<no[b].first){      //其中一个是另一个的祖先结点
    			   while(no[a].first<no[b].first)b=no[b].second;
    			}else{
    			   while(no[a].first>no[b].first)a=no[a].second;
    			}
    			if(a==b)printf("%d is an ancestor of %d.\n",a==x?a:b,a==x?y:x);
    			else{    //达到同一层,两个不等
    			  while(a!=b)a=no[a].second,b=no[b].second;
    			  printf("LCA of %d and %d is %d.\n",x,y,a);
    			}
			}
		}
	}	
	return 0;
 } 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值