给定一棵二叉树(保证非空)以及这棵树上的两个节点对应的data值 p 和 q,请找到 p 和 q 的最近公共祖先节点。要注意的是不包括p q点本身,也就是说a b c d * * * * *的二叉树中,c d公共祖先是b而不是c。
本题不认为查找点本事(p q)是祖先结果,故不能用寻常的递归解决,我在普通递归的基础上加了额外判断结果是否为p q的语句,如果是的话则证明查找点在同侧则使用travel函数重新查找
题主建议先把普通递归理解完了再理解此题,多少有些绕,我想了很久。
哎继续加油吧
如果有错或者更好的办法欢迎评论区指正~
【输入样例】a b c d * * * * *
c d
【输出结果】b
typedef struct BitNode
{
char data;
BitNode *lchild,*rchild;
int flag;
}BitNode,*Bitree;
typedef struct LinkNode
{
BitNode *data;
LinkNode *next;
}LinkNode;
typedef struct
{
LinkNode *front,*rear;
}Linkque;
void Initque(Linkque &q)
{
q.front=q.rear=(LinkNode *)malloc(sizeof(LinkNode));
q.front->next=NULL;
}
int isempty(Linkque q)
{
if(q.front==q.rear) return 0;
else return 1;
}
void enque(Linkque &q,BitNode *x)
{
LinkNode *s;
s=(LinkNode *)malloc(sizeof(LinkNode));
if(s!=NULL)
{
s->data=x;
s->next=NULL;
q.rear->next=s;
q.rear=s;
}
}
bool deque(Linkque &q,Bitree &x)
{
if(q.front==q.rear) return false;//队空
else
{
LinkNode *p=q.front->next;
x=p->data;
q.front->next=p->next;
if(p==q.rear)
{
q.rear=q.front;
}
free(p);
return true;
}
}
void Precreat(Bitree &T) //根左右
{
char ch;
scanf("%c",&ch);
getchar();
if(ch=='*') T=NULL;
else
{
BitNode *s=(BitNode *)malloc(sizeof(BitNode));
s->data=ch;
T=s;
Precreat(T->lchild);
Precreat(T->rchild);
}
}
void Levelorder(Bitree T) //层次遍历
{
Linkque q;
Initque(q);
BitNode *s;
enque(q,T);
T->flag=1;
while(isempty(q)!=0)
{
deque(q,s);
// printf("%c (%d)",s->data,s->flag);
if(s->lchild!=NULL)
{
enque(q,s->lchild);
s->lchild->flag=s->flag+1;
}
if(s->rchild!=NULL)
{
enque(q,s->rchild);
s->rchild->flag=s->flag+1;
}
}
}
int findp=0,findq=0;
void Preorder(Bitree T,char p,char q) //先序遍历 根左右
{
if(T!=NULL)
{
// printf("%c ",T->data);
if(T->data==p) findp=T->flag;
if(T->data==q) findq=T->flag;
Preorder(T->lchild,p,q);
Preorder(T->rchild,p,q);
}
}
BitNode *travel1(Bitree T,char p,char q)//最近共同祖先
{
if(T==NULL) return T;
if(T->data==p || T->data==q) return T;
BitNode *left=travel1(T->lchild,p,q);
BitNode *right=travel1(T->rchild,p,q);
if(left==NULL &&right !=NULL) return right;
if(left!=NULL &&right ==NULL) return left;
if(left!=NULL &&right !=NULL) return T;
else return NULL;
}
BitNode * travel(Bitree T,char p,char q)
{
if(T->data==p ||T->data==q) return T;
Linkque q1;
Initque(q1);
BitNode *s;
enque(q1,T);
int min;
if(findp>findq) min=findq;
else min=findp;
// printf("min=%d",min);
while(isempty(q1)!=0)
{
deque(q1,s);
if(s->lchild!=NULL)
{
if(s->lchild->data==p || s->lchild->data==q) return s;
}
if(s->rchild!=NULL)
{
if(s->rchild->data==p || s->rchild->data==q) return s;
}
{
if(s->lchild!=NULL && s->lchild->flag<=min-1)
{
enque(q1,s->lchild);
}
if(s->rchild!=NULL && s->rchild->flag<=min-1)
{
enque(q1,s->rchild);
}
}
}
}
main()
{
Bitree T;
Precreat(T);
BitNode *z;
char p,q;
scanf("%c",&p);
getchar();
scanf("%c",&q);
getchar();
Levelorder(T);
Preorder(T,p,q);
// printf("%d %d",findp,findq);
int gtr=1;
z=travel1(T,p,q);
if(z->data==p || z->data==q) gtr=0;
if(gtr==0)
{
z=travel(T,p,q);
}
printf("%c",z->data);
return 0;
}