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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
火车站的列车调度是指通过对铁轨进行合理的安排和调度,使得不同的列车能够按照预定的时刻表顺利地到达和离开火车站。这对于维持交通秩序和提高运输效率至关重要。 首先,火车站的铁轨结构应当考虑列车的进站、出站、交会、终点等不同状态下的需要。一般来说,铁轨由主线、岔道和调车场组成。主线是列车运行的主要通道,需要保证线路畅通无阻;岔道则用于分流列车,使得不同的列车可以按照预定的方向进出火车站;调车场则是列车停靠、排列和接发的地方。 其次,列车的调度需要考虑列车的时刻表和运行速度。在编制时刻表时,需要根据列车的始发、途经和终点站之间的距离、客流量以及所需的运行时间等因素进行合理的安排。同时,还需要根据火车站内部的交通流量情况,灵活地调整列车的发车间隔,避免拥堵和延误。 另外,列车的调度还需要考虑到列车车辆的停靠和编排。每趟列车到达火车站后,需要及时清理和检修车辆,并为下一班列车提供足够的时间和空间。在行车过程,列车的编排应当根据列车的目的地和途径站点进行合理的安排,以防止交叉冲突和阻塞。 总之,火车站的列车调度是一个复杂而重要的任务,需要对铁轨进行合理的结构设计,并根据时刻表和列车运行速度进行精确的调度安排。只有通过科学合理的调度,才能确保列车能够安全、高效地到达和离开火车站。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

约束112

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

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

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

打赏作者

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

抵扣说明:

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

余额充值