查找最近公共祖先结点

问题描述

假设指针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;
    }
}

猜你喜欢

转载自blog.csdn.net/u013009576/article/details/77568533