问题描述
假设指针p和指针q分别指向二叉树中任意两个节点的指针,试编写算法找到p和q的最近公共祖先节点r
算法思想
因为计算的是公共祖先节点,因此可以考虑使用非递归后序遍历的思想。在非递归后序遍历的算法实现中,栈里面存放了即将入栈的元素的所有祖先节点。
为了方便表示说明,这里使用下图所描述的二叉树来说明。
假设指针p指向节点E,指针q指向节点G。
- 按照正常的非递归后序遍历算法进行遍历,即借助栈
S
完成;- 当遍历到节点E时,将此时栈
S
中的元素复制到临时栈S1
中。此时栈S1
中的所有元素便为节点E的全部祖先节点;- 当编列到节点G时,将此时栈
S
中的元素复制到临时栈S2
中。此时栈S2
中的所有元素便为节点G的全部祖先节点;- 最后在分别按照从栈顶到栈底的顺序寻找栈
S1
和栈S2
中的公共因子便可,第一个匹配到的便是节点E和节点G的最近公共祖先节点。
算法描述
void PostOrder(BiTNode* T)
{
BiTNode *p=T;
BiTNode *r=NULL;
SqStack S;
InitStack(&S);
SqStack S1;
InitStack(&S1);
SqStack S2;
InitStack(&S2);
int flag=1;
while(IsEmptyStack(&S)!=0||p!=NULL){
if(p){
Push(&S,p);
p=p->lchild;
}else{
p=GetTop(&S);
if(p->data==‘E‘){
for(int i=0;i<=S.top;i++){
S1.data[i]=S.data[i];
S1.top=S.top;
}
}
if(p->data==‘G‘){
for(int i=0;i<=S.top;i++){
S2.data[i]=S.data[i];
S2.top=S.top;
}
}
if(p->rchild!=NULL&&p->rchild!=r){
p=p->rchild;
Push(&S,p);
p=p->lchild;
}else{
p=Pop(&S);
if(IsEmptyStack(&S1)!=0&&IsEmptyStack(&S2)!=0){
for(int i=S1.top;i>-1&&flag;i--){
for(int j=S2.top;j>-1;j--){
if(S1.data[i]==S2.data[j]){
printf("%c",S1.data[i]->data);
flag=0;
}
}
}
}
r=p;
p=NULL;
}
}
}
}
具体代码见附件。
附件
//AB#DF##G##C#E##
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 100
//---------------------------------------------------------------------
typedef char ElemType;
typedef struct BiTNode{
ElemType data;
struct BiTNode *lchild, *rchild;
}BiTNode,*BiTree;
typedef struct{
BiTNode* data[MaxSize];
int top;
}SqStack;
void InitStack(SqStack*);
void Push(SqStack*,BiTNode*);
BiTNode* Pop(SqStack*);
BiTNode* GetTop(SqStack*);
int IsEmptyStack(SqStack*);
BiTree CreateBiTree(BiTNode*);
void PostOrder(BiTNode*);
//---------------------------------------------------------------------
int main(int argc,char* argv[])
{
BiTNode *T;
T=(BiTNode*)malloc(sizeof(BiTNode));
T=CreateBiTree(T);
PostOrder(T);
printf("\n");
return 0;
}
//---------------------------------------------------------------------
BiTree CreateBiTree(BiTNode* T)
{
ElemType x;
scanf("%c",&x);
if(x==‘#‘){
return T=NULL;
}else{
T=(BiTNode*)malloc(sizeof(BiTNode));
T->data=x;
T->lchild=CreateBiTree(T->lchild);
T->rchild=CreateBiTree(T->rchild);
}
return T;
}
void PostOrder(BiTNode* T)
{
BiTNode *p=T;
BiTNode *r=NULL;
SqStack S;
InitStack(&S);
SqStack S1;
InitStack(&S1);
SqStack S2;
InitStack(&S2);
int flag=1;
while(IsEmptyStack(&S)!=0||p!=NULL){
if(p){
Push(&S,p);
p=p->lchild;
}else{
p=GetTop(&S);
if(p->data==‘E‘){
for(int i=0;i<=S.top;i++){
S1.data[i]=S.data[i];
S1.top=S.top;
}
}
if(p->data==‘G‘){
for(int i=0;i<=S.top;i++){
S2.data[i]=S.data[i];
S2.top=S.top;
}
}
if(p->rchild!=NULL&&p->rchild!=r){
p=p->rchild;
Push(&S,p);
p=p->lchild;
}else{
p=Pop(&S);
if(IsEmptyStack(&S1)!=0&&IsEmptyStack(&S2)!=0){
for(int i=S1.top;i>-1&&flag;i--){
for(int j=S2.top;j>-1;j--){
if(S1.data[i]==S2.data[j]){
printf("%c",S1.data[i]->data);
flag=0;
}
}
}
}
r=p;
p=NULL;
}
}
}
}
//---------------------------------------------------------------------
void InitStack(SqStack* S){
S->top=-1;
}
void Push(SqStack* S,BiTNode* T){
if(S->top==MaxSize-1){
return;
}
S->data[++S->top]=T;
}
BiTNode* Pop(SqStack* S){
if(S->top==-1){
return NULL;
}
return S->data[S->top--];
}
BiTNode* GetTop(SqStack* S){
if(S->top==-1){
return NULL;
}
return S->data[S->top];
}
int IsEmptyStack(SqStack* S){
if(S->top==-1){
return 0;
}else{
return -1;
}
}
时间: 2024-11-07 13:03:19