浙大 PAT 甲级 1151 LCA in a Binary Tree

 

思路和题1143一样,只不过寻找时不能再依靠BST的性质来判断左右子树,可以在构建树时将 该节点是父节点的左子树或是右子树 这一信息保存在每个节点中。

思路一样,但这题卡了很久…因为遗漏了一个细节,回溯时我只考虑了寻找父节点的左子树或右子树,而没有考虑到父节点就可能是我们要寻找的u或v。一直出现段错误,题1143也出现段错误,是因为没有考虑u,v相等且都为根节点的情况。总之,使用指针很容易由于考虑不周全而出现段错误。最后发现错误的方法是,自己写了一个样例,不停的测试。

考试时出现段错误或部分样例不通过的情况下,首先读题,再看代码,然后自己举例测试。总之要镇定,不要放弃。

#include<stdio.h>
#include<stdlib.h>
typedef struct Node* Tree;
struct Node
{
    int key;
    Tree left;
    Tree right;
    Tree parent;
    bool isLeft;
};
int preorder[10005], inorder[10005];
Tree construct(int s1, int e1, int s2, int e2, Tree parent, bool isLeft)
{
    if (s1 > e1 || s2 > e2) return NULL;
    if (s1 == e1 || s2 == e2)
    {
        Tree T = (Tree)malloc(sizeof(Node));
        T->key = preorder[s1];
        T->parent = parent;
        T->isLeft = isLeft;
        T->left = T->right = NULL;
        return T;
    }
    else
    {
        Tree T = (Tree)malloc(sizeof(Node));
        T->key = preorder[s1];
        T->parent = parent;
        T->isLeft = isLeft;
        T->left = T->right = NULL;
        int index = s2;
        for (index = s2; index <= e2; index++)
        {
            if (inorder[index] == T->key)
            {
                break;
            }
        }
        T->left = construct(s1 + 1, s1 + index - s2, s2, index - 1, T, true);
        T->right = construct(s1 + index - s2 + 1, e1, index + 1, e2, T, false);
        return T;
    }
}
Tree find(int x, Tree T)
{
    if (T == NULL) return NULL;
    if (T->key == x) return T;
    Tree leftResult = find(x, T->left);
    if (leftResult != NULL) return leftResult;
    Tree rightResult = find(x, T->right);
    if (rightResult != NULL) return rightResult;
    return NULL;
}
int getLCA(Tree T, int U, int V)
{
    if (T->key == U) return U;
    if (T->key == V) return V;
    Tree uptr = find(U, T); // 不为空,因为前面已经判断U是存在的
    if (find(V, uptr) != NULL) return U; // U下面能够找到V
    Tree upptr = uptr->parent; // U的父节点不为空
    while (upptr != NULL)
    {
        if (upptr->key == V)
        {
            return upptr->key;
        }
        if (uptr->isLeft == true)
        {
            Tree tmp = find(V, upptr->right);
            if (tmp != NULL) return upptr->key;
        }
        if (uptr->isLeft == false)
        {
            Tree tmp = find(V, upptr->left);
            if (tmp != NULL) return upptr->key;
        }
        uptr = upptr;
        upptr = uptr->parent;
    }
}
int main()
{
    int M, N;
    scanf("%d%d", &M, &N);
    for (int i = 0; i < N; i++)
    {
        scanf("%d", &inorder[i]);
    }
    for (int i = 0; i < N; i++)
    {
        scanf("%d", &preorder[i]);
    }
    Tree T = construct(0, N - 1, 0, N - 1, NULL, true);
    for (int i = 0; i < M; i++)
    {
        int u, v;
        scanf("%d%d", &u, &v);
        bool hasu = (find(u, T) != NULL);
        bool hasv = (find(v, T) != NULL);
        if (hasu == false && hasv == false)
        {
            printf("ERROR: %d and %d are not found.\n", u, v);
            continue;
        }
        if (hasu == false && hasv == true)
        {
            printf("ERROR: %d is not found.\n", u);
            continue;
        }
        if (hasu == true && hasv == false)
        {
            printf("ERROR: %d is not found.\n", v);
            continue;
        }
        if (u == v)
        {
            printf("%d is an ancestor of %d.\n", u, v);
            continue;
        }
        int ans = getLCA(T, u, v);
        if (ans == u)
        {
            printf("%d is an ancestor of %d.\n", u, v);
            continue;
        }
        if (ans == v)
        {
            printf("%d is an ancestor of %d.\n", v, u);
            continue;
        }
        printf("LCA of %d and %d is %d.\n", u, v, ans);
    }
    return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值