最低共同祖先 - 代码解释

时间:2015-10-06 09:26:14

标签: algorithm binary-tree lowest-common-ancestor

通过顺序和后序遍历的LCA很容易被我实现和理解。

但是,有一种递归的自下而上的方法。

我在线看了一下代码,我不明白一行:

以下是代码:

public Node lowestCommonAncestor(int val1, int val2,Node root){
    if(root == null){
        return null;
    }
    if(root.data == val1 || root.data == val2){
        return root;
    }

    Node left = lowestCommonAncestor(val1, val2, root.left);
    Node right = lowestCommonAncestor(val1, val2, root.right);

    if(left != null && right != null){
        return root;
    }
    return left != null ? left : right;
}

val1和val2是两个节点的值,需要找到其LCA。

最后一行是我被困住的地方。

return left != null ? left : right;

有人可以解释一下吗?

谢谢。

2 个答案:

答案 0 :(得分:2)

这是一种简洁的实用方法,但是从上到下而不是标准的从底部到顶部实现。让我们尝试分析lowestCommonAncestor(int val1, int val2,Node root)返回的内容。

如果在left的左子树中找到val1val2中的至少一个,则

root将不为空。当且仅当在val1的右子树中找到val2root中的至少一个时,类似的权利才会为空。显然if语句if(left != null && right != null){将是真的,当且仅当精确在左子树中找到val1val2之一且精确在右子树中找到val1val2中的一个。因此,这仅适用于val1val2的最低共同祖先(如果需要,可以绘制图片)。对于此节点,将返回根。对于所有其他节点,该函数将返回左侧或右侧子树中的lowestCommonAncestor,具体取决于哪一个不为null,如果两者都为null,则返回null。

因此,对于LCA上方的所有节点,正确和左侧中的一个节点将不为空(如val1val2将在其中一个子树中)并且这将是其中的根LCA所在的子树。因此,对于LCA以上的所有节点,lowestCommonAncestor的调用的返回值将是LCA本身。作为一个conequence,对原始树的根的调用将真正是LCA。

答案 1 :(得分:1)

// Method to find lowest common ancestor.
public Node lowestCommonAncestor(int val1, int val2,Node root){

    // Base condition to terminate.
    if(root == null){
        return null;
    }

    // While traversing, if we found root itself equal to val1/val2.
    // Then, root should be the lowest common ancestor.
    if(root.data == val1 || root.data == val2){
        return root;
    }

    // If not, do post-order traversing. Means, left node, then right 
    // node, then root iteslf (current node.)
    Node left = lowestCommonAncestor(val1, val2, root.left);
    Node right = lowestCommonAncestor(val1, val2, root.right);

    // While traversing, if we reach to a state, when root itself has left and 
    // right both children, then, this is the lowest common ancestor of val1, 
    // and val2. return this root.
    if(left != null && right != null){
        return root;
    }

    // If, root has only one child either  left or right child, then start 
    // traversing into that child.
    // If, root has no child, in that case. Return null. Means this tree does    
    // not contain lowest common ancestor of val1, and val2.
    return left != null ? left : right;
}

我通过发表评论来解释整个代码。我认为这会更有意义。请仔细阅读。如果您还有任何疑问,请随时提出。