进阶实验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("\n");
    }

    return 0;
}

原文地址:https://www.cnblogs.com/snzhong/p/12580351.html

时间: 2024-07-30 13:22:22

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

二叉搜索树的操作集(30 分)

6-12 二叉搜索树的操作集(30 分) 本题要求实现给定二叉搜索树的5种常用操作. 函数接口定义: BinTree Insert( BinTree BST, ElementType X ); BinTree Delete( BinTree BST, ElementType X ); Position Find( BinTree BST, ElementType X ); Position FindMin( BinTree BST ); Position FindMax( BinTree BST

LeetCode 235. 二叉搜索树的最近公共祖先(Lowest Common Ancestor of a Binary Search Tree) 32

235. 二叉搜索树的最近公共祖先 235. Lowest Common Ancestor of a Binary Search Tree 题目描述 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:"对于有根树 T 的两个结点 p.q,最近公共祖先表示为一个结点 x,满足 x 是 p.q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)." 例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,nul

【leetcode 简单】 第六十八题 二叉搜索树的最近公共祖先

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:"对于有根树 T 的两个结点 p.q,最近公共祖先表示为一个结点 x,满足 x 是 p.q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)." 例如,给定如下二叉搜索树:  root = [6,2,8,0,4,7,9,null,null,3,5] _______6______ / ___2__ ___8__ / \ / 0 _4 7 9 / 3 5 示例 1: 输入: root

树、递归、遍历————二叉搜索树的最近公共祖先

可以根据二叉搜索树的特点来进行解题: 二叉搜索树左边节点的值小于根节点 右边节点的值大于根节点. 所以左右都小于根节点的值说明在左子树上 左右的值大于根节点的值就代表值在右子树上 介于两者中间则输入的本身就是根节点,即为最近公共祖先. 一.遍历 1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * Tr

leetcode 235. 二叉搜索树的最近公共祖先(c++)

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p.q,最近公共祖先表示为一个结点 x,满足 x 是 p.q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先).” 例如,给定如下二叉搜索树:  root = [6,2,8,0,4,7,9,null,null,3,5] 示例 1: 输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8输出: 6 解释: 节点

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

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p.q,最近公共祖先表示为一个结点 x,满足 x 是 p.q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先).” 例如,给定如下二叉搜索树:  root = [6,2,8,0,4,7,9,null,null,3,5] 示例 1: 输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8输出: 6 解释: 节点

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

题目链接:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-search-tree/submissions/ 解题思路: 如果p和q都小于root,去左边找就行. 如果p和q在两侧的,直接就是root,这个可以通过val来判断. 1 /** 2 * Definition for a binary tree node. 3 * public class TreeNode { 4 * int val; 5 * Tr

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

根据236的做法,这个就简单了. 递归主要费时间的地方是,分别去左右子树去找,有没有p和q. 利用搜索树的性质,减少递归的次数 如果p和q都小于root,去左边找就行. 如果p和q在两侧的,直接就是root,这个可以通过val来判断. public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { //返回条件一样 //如果往下的过程中,先遇到p或者q,它就是最近祖先 if(root==null||roo

6-12 二叉搜索树的操作集

6-12 二叉搜索树的操作集(30 分) 本题要求实现给定二叉搜索树的5种常用操作. 函数接口定义: BinTree Insert( BinTree BST, ElementType X ); BinTree Delete( BinTree BST, ElementType X ); Position Find( BinTree BST, ElementType X ); Position FindMin( BinTree BST ); Position FindMax( BinTree BST