题目描述
给定一棵二叉搜索树的先序遍历序列,要求你找出任意两结点的最近公共祖先结点(简称 LCA)。
输入
输入的第一行给出两个正整数:待查询的结点对数 M(≤ 1 000)和二叉搜索树中结点个数 N(≤ 10 000)。随后一行给出 N 个不同的整数,为二叉搜索树的先序遍历序列。最后 M 行,每行给出一对整数键值 U 和 V。所有键值都在整型int范围内。
输出
对每一对给定的 U 和 V,如果找到 A
是它们的最近公共祖先结点的键值,则在一行中输出 LCA of U and V is A.
。但如果 U 和 V 中的一个结点是另一个结点的祖先,则在一行中输出 X is an ancestor of Y.
,其中 X
是那个祖先结点的键值,Y
是另一个键值。如果 二叉搜索树中找不到以 U 或 V 为键值的结点,则输出 ERROR: U is not found.
或者 ERROR: V is not found.
,或者 ERROR: U and V are not found.
。
输入样例 | 输出样例 |
6 8 6 3 1 2 5 4 8 7 2 5 8 7 1 9 12 -3 0 8 99 99 | LCA of 2 and 5 is 3. 8 is an ancestor of 7. ERROR: 9 is not found. ERROR: 12 and -3 are not found. ERROR: 0 is not found. ERROR: 99 and 99 are not found. |
//1.search函数搜索data是否存在,并在不存在时打印缺失信息(注意,区分两个都找不到,和其中一个找不到的区别)
//2.如若都能找到,也分两种情况:(1)不互为直系亲属(2)互为直系亲属
//主要思路:利用唯一根的特性,给node添加parent指针,通过反向打印分支,并对比分支重复部分,找到最小祖先
//默认二叉树的组树过程遵从二叉排序
#include<iostream>
#include<string>
using namespace std;
class binode{
public:
string data;
binode *rchild,*lchild,*parent;
binode(){
rchild = nullptr;lchild = nullptr;parent = nullptr;data="#";
}
};
binode *root;
string nothing="#";
string map_find(binode *root){
if(root->parent){
string p = map_find(root->parent);
return p+root->data;
}
else
return root->data;
}
//flag==1:匹配模式,flag==0:组树模式。
string search_node(binode *&root,binode *&p_root,string k,const int flag){
string final="#";
if(root){
if(root->data == k){
if(flag==1){
string p = map_find(root);
return p;
}
return nothing;
}
else{
if(k < root->data){
final = search_node(root->rchild,root,k,flag);
}
else
final = search_node(root->lchild,root,k,flag);
}
}
else if(flag==0){
binode *s = new binode();
s->data = k;
s->parent = p_root;
root = s;
}
if(final=="#")
return nothing;
else
return final;
}
void use_search(string t1,string t2){
string f1,f2;
f1=search_node(root,root,t1,1);
f2=search_node(root,root,t2,1);
if(f1=="#"||f2=="#"){
if(f1=="#"&&f2=="#"){
cout<<"ERROR: "<<t1<<" and "<<t2<<" are not found."<<endl;
}
else if(f1=="#"){
cout<<"ERROR: "<<t1<<" is not found."<<endl;
}
else
cout<<"ERROR: "<<t2<<" is not found."<<endl;
}
else{
int l1=f1.length(),l2=f2.length();
if(l2>l1&&f1[l1-1]==f2[l1-1]){
cout<<t1<<" is an ancestor of "<<t2<<"."<<endl;
}
else if(l1>l2&&f1[l2-1]==f2[l2-1]){
cout<<t2<<" is an ancestor of "<<t1<<"."<<endl;
}
else{
int i;
for(i = 0 ; i < l1&&i < l2 ; i++ ){
if(f1[i]!=f2[i])
break;
}
cout<<"LCA of "<<t1<<" and "<<t2<<" is "<<f1[i-1]<<"."<<endl;
}
}
}
int main(){
int t_match,t_node;
cin>>t_match>>t_node;
root = nullptr;
string data;
cin>>data;
binode *s = new binode();
s->data =data;
root = s;
t_node--;
while(t_node--){
cin>>data;
search_node(root,root,data,0);
}
string t1,t2;
while(t_match--){
cin>>t1>>t2;
use_search(t1,t2);
}
return 0;
}