ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2020-03-27 11:55:52  阅读:172  来源: 互联网

标签:rt p1 进阶 parent int 30 Tree 2.3 data


 

 

 

 

 

 解题思路:

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("\n");
    }

    return 0;
}

 

标签:rt,p1,进阶,parent,int,30,Tree,2.3,data
来源: https://www.cnblogs.com/snzhong/p/12580351.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有