E. 二叉搜索树的最近公共祖先

题目描述

给定一棵二叉搜索树的先序遍历序列,要求你找出任意两结点的最近公共祖先结点(简称 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;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值