zoukankan      html  css  js  c++  java
  • 进阶实验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;
    }
  • 相关阅读:
    进程池,线程池,协程,gevent模块,协程实现单线程服务端与多线程客户端通信,IO模型
    线程相关 GIL queue event 死锁与递归锁 信号量l
    生产者消费者模型 线程相关
    进程的开启方式 进程的join方法 进程间的内存隔离 其他相关方法 守护进程 互斥锁
    udp协议 及相关 利用tcp上传文件 socketserver服务
    socket套接字 tcp协议下的粘包处理
    常用模块的完善 random shutil shevle 三流 logging
    day 29 元类
    Django入门
    MySQL多表查询
  • 原文地址:https://www.cnblogs.com/snzhong/p/12580351.html
Copyright © 2011-2022 走看看