7-1 二叉搜索树的最近公共祖先 (40 分)
给定一棵二叉搜索树的先序遍历序列,要求你找出任意两结点的最近公共祖先结点(简称 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.
分析
分析题目:
输入的数据为:
① 待查询的结点对数 M和二叉搜索树中结点个数 N。
②随后一行给出 N 个不同的整数,为二叉搜索树的先序遍历序列。
③最后 M 行,每行给出一对整数键值 U 和 V。
数据处理:
对于数据①,用来控制数据②和③的输入次数
对于数据②,可以用来构造排序二叉树,具体看排序二叉树的构造方法
对于数据③,依次判断
1)是否存在于二叉树中
2)是否是祖先
3)找出共同的最小的祖先
代码
#include <iostream>
#include <malloc.h>
#include<bits/stdc++.h>
using namespace std;
typedef struct node
{
int data;
struct node *left,*right;
}tree;
//创建
void createTree(tree *&t,int data)
{
if(t==NULL)
{
t = (tree *)malloc(sizeof(tree));
t->data=data;t->left=NULL;t->right=NULL;
}
else
{
if(t->data > data)
return createTree(t->left,data);
if(t->data < data)
return createTree(t->right,data);
}
}
//判断存在
bool isfind(tree *t,int x)
{
if(t!=NULL)
{
if(t->data==x)
return true;
else if(t->data<x)
return isfind(t->right,x);
else if(t->data>x)
return isfind(t->left,x);
}else return false;
}
//判断是否是祖先
bool Find(tree * t,int x)
{
if(t!=NULL)
{
if(t->data==x)
return true;
if(x<t->data)
return Find(t->left,x);
else
return Find(t->right,x);
}
return false;
}
bool Find_F(tree *t,int u,int v)
{
if(u==v)
return true;
if(t!=NULL)
{
if(t->data==u)
if(Find(t,v))
return true;
if(u<t->data)
return Find_F(t->left,u,v);
else
return Find_F(t->right,u,v);
}
else
return false;
}
//判断是否是LCA
int Find_LCA(tree * t,int u,int v)
{
if(u<t->data && v<t->data)
return Find_LCA(t->left,u,v);
else if(u>t->data && v>t->data)
return Find_LCA(t->right,u,v);
else
{
return t->data;
}
}
int main()
{
int m,n,i,data;
tree *t=NULL;
cin >> m;cin >> n;
for(i=0;i<n;i++)
{
cin >> data;
createTree(t,data);
}
int u,v;
bool hasu,hasv;
for(i=0;i<m;i++)
{
cin >> u;cin >> v;
hasu=isfind(t,u);
hasv=isfind(t,v);
if(!hasu&&!hasv)
cout<<"ERROR: "<<u<<" and "<<v<<" are not found."<<endl;
else if(!hasu)
cout<<"ERROR: "<<u<<" is not found."<<endl;
else if(!hasv)
cout<<"ERROR: "<<v<<" is not found."<<endl;
else
{
if(Find_F(t,u,v))
cout << u<<" is an ancestor of "<<v<<"."<<endl;
else if(Find_F(t,v,u))
cout << v<<" is an ancestor of "<<u<<"."<<endl;
else
{
int lca;
lca=Find_LCA(t,u,v);
cout << "LCA of "<<u<<" and "<<v<<" is "<<lca<<"."<<endl;
}
}
}
return 0;
}