修改二进制树的LCA代码以检查Java中是否存在节点

时间:2014-01-29 17:34:05

标签: java algorithm binary-tree least-common-ancestor

我有这段代码,用于计算Least common Ancestor中给定的两个nodes的{​​{1}}。 目前,它假设两个节点都存在。我可以编写一个辅助方法来检查节点是否存在,然后调用Binary tree方法。这将需要遍历树两次。我想知道当我的当前代码不存在节点时是否有办法检查和处理情况。

LCABT

1 个答案:

答案 0 :(得分:2)

让函数返回一对(state, lca)state必须是以下之一:

0: Neither v1 nor v2 appear at or under root; lca is meaningless.
1: Only v1 appears at or under root; lca is meaningless.
2: Only v2 appears at or under root; lca is meaningless.
3: Both v1 and v2 appear at or under root, and have LCA equal to lca.

该功能应从检查基本情况开始:

LCABT(Node root, int v1, int v2) {
    if (root == null) then return (0, null);

否则,递归其左右儿童,看看其中一个是否能自行解决问题:

    (s1, lca1) = LCABT(root.left, v1, v2);
    (s2, lca2) = LCABT(root.right, v1, v2);

如果s1s2为3,则已找到LCA(分别为lca1lca2)并可立即返回。 (实际上,你甚至可以在第二次调用s1 == 3之前检查LCABT()是否获得加速:如果是,那么我们已经拥有了LCA并且不需要第二次调用。)

    if (s1 == 3) then return (3, lca1);
    if (s2 == 3) then return (3, lca2);

否则,设置s = s1 | s2(即按位OR)。如果s == 3我们知道root是LCA,但我们尚未考虑所有方式,它可以是LCA:它仍然可以是LCA时只有v1v2中的一个出现在其子级或其子级下,前提是另一个值位于root本身:

    s = s1 | s2;
    if (root.data == v1) then s = s | 1;
    if (root.data == v2) then s = s | 2;

现在所有root都是LCA的情况都是s == 3,所以如果s == 3那么我们可以立即返回(3, root)

    if (s == 3) then return (3, root);

否则,v1v2中只有一个位于root或之下,因此我们应该返回一个值,表明它是哪一个:

    return (s, null);
}

最后,对LCABT()的原始顶级调用显然应该仅在函数返回state值为3时才将该函数视为成功。

此算法相对于您的算法的另一个优点是,它不会被树中v1v2的重复副本所迷惑。