进阶实验8-2.3 二叉搜索树的最近公共祖先 (30分)

Posted snzhong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了进阶实验8-2.3 二叉搜索树的最近公共祖先 (30分)相关的知识,希望对你有一定的参考价值。

技术图片

 

 

 技术图片

 

 

 解题思路:

1、定义一个结构体,来存储二叉排序树

typedef struct {
	int data;
	int left;
	int right;
	int parent;
	int h;
} T;

2、再定义一个结构体,将输入数据存入

typedef struct {
    int data;
    int pos;
} Info;

3、对输入数据排序

4、用二分法确实查询数据是否存在树中

5、寻找最近公共祖先

     1)如果x,y均不是根结点

         1.1、如果x==y,则x是y的祖先

         1.2、若x,y分别在左右子树,则根结点是x和y的最近公共祖先

         否则,

         1.2.1、若x的高度>y的高度,则如果x的双亲==y,则y是x的祖先,查询结束;否则,判断x的双亲高度和y的高度;

         1.2.2、若x的高度<y的高度,则如果y的双亲==x,则x是y的祖先,查询结束;否则,判断y的双亲高度和x的高度;

         1.2.3、若x的高度=y的高度,则如果x的双亲==y的双亲,则x的双亲是x和y的最近公共祖先,查询结束;否则,判断x的双亲高度和y的双亲高度

         重复以上三步

     2)否则,若x是根结点,则x是的祖先

     3) 否则,若y是根结点,则y是x的祖先

#include <stdio.h>
#define Max 10000
typedef struct {
    int data;
    int left;
    int right;
    int parent;
    int h;
} T;
typedef struct {
    int data;
    int pos;
} Info;
T Tree[Max];
void CreateSearchTree(Info a[],int n) {
    int i=0,k=0;
    Tree[k].data=a[i].data;
    Tree[k].parent=-1;
    Tree[k].left=-1;
    Tree[k].right=-1;
    Tree[k].h=1;
    k++;
    for(i=1; i<n; i++) {
        int rt=0,h=1;;
        while(1) {
            int flag=0;
            if(a[i].data<Tree[rt].data) {
                h++;
                if(Tree[rt].left==-1) {
                    Tree[rt].left=i;
                    Tree[k].data=a[i].data;
                    Tree[k].parent=rt;
                    Tree[k].left=-1;
                    Tree[k].right=-1;
                    Tree[k].h=h;
                    k++;
                    flag=1;
                    break;
                } else {
                    rt=Tree[rt].left;
                }
            } else if(a[i].data>Tree[rt].data) {
                h++;
                if(Tree[rt].right==-1) {
                    Tree[rt].right=i;
                    Tree[k].data=a[i].data;
                    Tree[k].parent=rt;
                    Tree[k].left=-1;
                    Tree[k].right=-1;
                    Tree[k].h=h;
                    k++;
                    flag=1;
                    break;
                } else {
                    rt=Tree[rt].right;
                }
            }
            if(flag)
                break;
        }
    }
}
int cmp(Info *a,Info *b) {
    return (*a).data-(*b).data;
}
int getPos(int x,Info a[],int n) {
    int i=0,j=n-1,mid;
    while(i<=j) {
        if(x==a[i].data)
            return a[i].pos;
        if(x==a[j].data)
            return a[j].pos;
        mid=(i+j)/2;
        if(x<a[mid].data) {
            j=mid-1;
        } else if(x>a[mid].data) {
            i=mid+1;
        } else
            return a[mid].pos;
    }
    return -1;

}
void Find(int p1,int p2,int rt) {
    int x=Tree[p1].data,y=Tree[p2].data,root=Tree[rt].data;
    int h1=Tree[p1].h,h2=Tree[p2].h;
    if(p1!=rt&&p2!=rt) {
        if(p1==p2)
            printf("%d is an ancestor of %d.",x,y);
        else {
            if((x<root&&y>root)||(x>root&&y<root)) {
                printf("LCA of %d and %d is %d.",x,y,root);
            } else {
                while(1) {
                    int flag=0;
                    if(h1>h2) {
                        int parent=Tree[p1].parent;
                        if(Tree[parent].data==y) {
                            printf("%d is an ancestor of %d.",y,x);
                            flag=1;
                            break;
                        } else {
                            p1=Tree[p1].parent;
                            h1=Tree[p1].h;
                        }
                    } else if(h1<h2) {
                        int parent=Tree[p2].parent;
                        if(Tree[parent].data==x) {
                            printf("%d is an ancestor of %d.",x,y);
                            flag=1;
                            break;
                        }  else {
                            p2=Tree[p2].parent;
                            h2=Tree[p2].h;
                        }
                    } else {
                        int t1=Tree[p1].parent,t2=Tree[p2].parent;
                        if(Tree[t1].data==Tree[t2].data) {
                            printf("LCA of %d and %d is %d.",x,y,Tree[t1].data);
                            flag=1;
                            break;
                        } else {
                            p1=Tree[p1].parent;
                            p2=Tree[p2].parent;
                            h1=Tree[p1].h;
                            h2=Tree[p2].h;
                        }
                    }
                    if(flag)
                        break;
                }
            }
        }
    } else if(x==root)
        printf("%d is an ancestor of %d.",x,y);
    else if(y==root)
        printf("%d is an ancestor of %d.",y,x);
}
int main() {
    int n,m;
    scanf("%d %d",&n,&m);
    Info a[m];
    int i;
    for(i=0; i<m; i++) {
        scanf("%d",&a[i].data);
        a[i].pos=i;
    }
    CreateSearchTree(a,m);
    qsort(a,m,sizeof(a[0]),cmp);
    int x,y;
    for(i=0; i<n; i++) {
        scanf("%d %d",&x,&y);
        int p1=getPos(x,a,m);
        int p2=getPos(y,a,m);
        if(p1!=-1&&p2!=-1) {
            Find(p1,p2,0);
        } else if(p1==-1&&p2!=-1) {
            printf("ERROR: %d is not found.",x);
        } else if(p1!=-1&&p2==-1) {
            printf("ERROR: %d is not found.",y);
        } else if(p1==-1&&p2==-1) {
            printf("ERROR: %d and %d are not found.",x,y);
        }
        printf("
");
    }

    return 0;
}

 

以上是关于进阶实验8-2.3 二叉搜索树的最近公共祖先 (30分)的主要内容,如果未能解决你的问题,请参考以下文章

二叉搜索树的最近公共祖先

235. 二叉搜索树的最近公共祖先

235. 二叉搜索树的最近公共祖先

算法二叉搜索树的最近公共祖先

[Leetcode]35. 二叉搜索树的最近公共祖先

求二叉搜索树的最近公共祖先(与那个普通二叉树最近公共祖先类似)