1151 LCA in a Binary Tree (30 point(s))

1151 LCA in a Binary Tree (30 point(s))

The lowest common ancestor (LCA) of two nodes U and V in a tree is the deepest node that has both U and V as descendants.

Given any two nodes in a binary tree, you are supposed to find their LCA.

Input Specification:

Each input file contains one test case. For each case, the first line gives two positive integers: M (≤ 1,000), the number of pairs of nodes to be tested; and N (≤ 10,000), the number of keys in the binary tree, respectively. In each of the following two lines, N distinct integers are given as the inorder and preorder traversal sequences of the binary tree, respectively. It is guaranteed that the binary tree can be uniquely determined by the input sequences. Then M lines follow, each contains a pair of integer keys U and V. All the keys are in the range of int.

Output Specification:

For each given pair of U and V, print in a line LCA of U and V is A. if the LCA is found and A is the key. But if A is one of U and V, print X is an ancestor of Y. where X is A and Y is the other node. If U or V is not found in the binary tree, print in a line ERROR: U is not found. or ERROR: V is not found. or ERROR: U and V are not found..

Sample Input:

6 8
7 2 3 4 6 5 1 8
5 3 7 2 6 4 8 1
2 6
8 1
7 9
12 -3
0 8
99 99

Sample Output:

LCA of 2 and 6 is 3.
8 is an ancestor of 1.
ERROR: 9 is not found.
ERROR: 12 and -3 are not found.
ERROR: 0 is not found.
ERROR: 99 and 99 are not found.

 LCA(最低公共祖先结点)。

注意点:

1. 结点的静态存储。

2. 树的重建,获得所在层次和父亲结点。

思路:

1. 先根据先序遍历和中序遍历重建树,注意保存结点的父亲结点下标所在层次。树的存储采取静态方式,方便通过结点的值找到结点。

2. 然后根据根据给出数对的数据找到这两个结点。

3. 注意到每一个非根结点的父亲结点是唯一的。将较低的结点向上回溯,直到所在的层次一样,如果此时就相等的,说明较高的结点是较低结点的祖先;否则同时回溯,直到结点相同。

参考链接:https://blog.youkuaiyun.com/richenyunqi/article/details/79839484

#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
int M,N;
const int MAX = 1e4+7;
struct Node{
	int data;int level;int father;//由于需要回溯,保存结点的父亲结点的下标(前序遍历的位置)和层次 
	Node(int d=0,int l=0,int f=-1):data(d),level(l),father(f){} 
};
Node pre[MAX];//结点静态存储 
int in[MAX];
void createTree(int root,int left,int right,int father,int level){
	//根据前序遍历的root位置和中序遍历的left和right的区间重建树 
	if(left>right) return;
	pre[root] =  Node(pre[root].data,level,father);
	int index = left;
	while(pre[root].data!=in[index]) index++;
	createTree(root+1,left,index-1,root,level+1);
	createTree(root+1+index-left,index+1,right,root,level+1);
}
int main(void){
	cin>>M>>N;
	for(int i=0;i<N;i++) cin>>in[i];
	for(int i=0;i<N;i++) cin>>pre[i].data;
	createTree(0,0,N-1,-1,0);
	int a,b;
	for(int i=0;i<M;i++){
		cin>>a>>b;
		int ai=N;int bi=N;
		for(int i=0;i<N;i++){//根据数据查询结点的下标 
			if(a==pre[i].data) ai = i;
			if(b==pre[i].data) bi = i;
		}
		if(ai==N&&bi==N) printf("ERROR: %d and %d are not found.\n",a,b);
		else if(ai==N&&bi!=N) printf("ERROR: %d is not found.\n",a);
		else if(ai!=N&&bi==N) printf("ERROR: %d is not found.\n",b);
		else{
			bool deeper = true;//Node a is deeper;
			if(pre[ai].level<pre[bi].level){
				deeper = false;
				swap(ai,bi);
			}
			while(pre[ai].level!=pre[bi].level) ai = pre[ai].father;//使得两个结点深度相同 
			if(ai==bi){
				printf("%d is an ancestor of %d.\n",(deeper?b:a),(deeper?a:b));//如果此时两个结点到了同一层 
			}
			else{
				while(ai!=bi){//否则同时向上回溯 
					ai = pre[ai].father;
					bi = pre[bi].father;
				}
				printf("LCA of %d and %d is %d.\n",a,b,pre[ai].data);
			}
		}
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值