查找最近公共祖先結點

版權聲明:本文爲博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/u013009576/article/details/77568533

問題描述

假設指針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;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章