PTA二叉搜索树中的最近公共祖先 分数 25 作者 陈越 单位 浙江大学

在一棵树T中两个结点u和v的最近公共祖先(LCA),是树中以u和v为其后代的深度最大的那个结点。现给定某二叉搜索树(BST)中任意两个结点,要求你找出它们的最近公共祖先。

函数接口定义:

int LCA( Tree T, int u, int v );

其中Tree的定义如下:

typedef struct TreeNode *Tree;
struct TreeNode {
    int   Key;
    Tree  Left;
    Tree  Right;
};

函数LCA须返回树T中两个结点u和v的最近公共祖先结点的键值。若u或v不在树中,则应返回ERROR。

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>

#define ERROR -1
typedef struct TreeNode *Tree;
struct TreeNode {
    int   Key;
    Tree  Left;
    Tree  Right;
};

Tree BuildTree(); /* 细节在此不表 */
int LCA( Tree T,  int u, int v );

int main()
{
    Tree T;
    int u, v, ans;

    T = BuildTree();
    scanf("%d %d", &u, &v);
    ans = LCA(T, u, v);
    if ( ans == ERROR ) printf("Wrong input\n");
    else printf("LCA = %d\n", ans);

    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例1 (对于下图给定的树):
在这里插入图片描述

2 7
输出样例1:
LCA = 6
输入样例2 (对于例1中的树):
1 9
输出样例2:
Wrong input
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB

答案:算法一(劣)

int Find(Tree T, int x)
{
    if (!T)return 0;
    if (T->Key == x)return 1;
    if (T->Key < x)return Find(T->Right, x);
    if (T->Key > x)return Find(T->Left, x);
}

int LCA(Tree T, int u, int v)
{
    if (!T)return ERROR;
    if (!Find(T, u) || !Find(T, v))return ERROR;
    if (u == T->Key || v == T->Key)return T->Key;
    if (u > T->Key && v < T->Key || u < T->Key && v > T->Key)return T->Key;
    if (u > T->Key)return LCA(T->Right, u, v);
    if (u < T->Key)return LCA(T->Left, u, v);
}

答案:算法二(优)

Tree Find(Tree T, int Key)
{
    if (T == NULL)return NULL;
    if (Key < T->Key)return Find(T->Left, Key);
    else if (Key > T->Key)return Find(T->Right, Key);
    else return T;
}

int LCA(Tree T, int u, int v)
{
    Tree uNode = Find(T, u);
    Tree vNode = Find(T, v);
    if (uNode == NULL || vNode == NULL)return ERROR;
    while (T != NULL)
    {
        if (u < T->Key && v < T->Key)T = T->Left;
        else if (u > T->Key && v > T->Key)T = T->Right;
        else return  T->Key;
    }
}

算法一Find函数中的逻辑判断不如算法二中的清晰简洁,并且在找到x的结点后并没有记录下结点的地址,仅仅是返回判断,有种浪费资源的感觉,所以算法二的Find函数更优秀。

算法一LCA函数中的逻辑判断更不如算法二中的清晰简洁,并且算法一的LCA函数仍然使用了递归,而算法二使用了迭代。

综上,使用算法二不仅能掌握清晰的逻辑结构,还能同时运用递归和迭代,岂不快哉。

本图片出自http://t.csdnimg.cn/aoP3Z
本图片转载自http://t.csdnimg.cn/aoP3Z

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

约束112

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值