查找最近公共祖先结点
来源:互联网 发布:地下城无限网络中断 编辑:程序博客网 时间:2024/06/05 14:42
问题描述
假设指针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; } } }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
具体代码见附件。
附件
//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; }}