简体   繁体   English

在二叉搜索树中找到两个节点的最低公共祖先

[英]Finding the lowest common ancestor of two nodes in a binary search tree - efficiently

Just wanted to know how efficient is the below algorithm to find the lowest common ancestor of two nodes in a binary search tree. 只是想知道以下算法在二进制搜索树中查找两个节点的最低公共祖先的效率如何。

Node getLowestCommonAncestor (Node root, Node a, Node b) {

   Find the in-order traversal of Node root.
   Find temp1 = the in-order successor of Node a.
   Find temp2 = the in-order successor of Node b.

   return min (temp1, temp2);
}

Searching for the lowest common ancestor in a binary search tree is simpler than that: observe that the LCA is the node where the searches for item A and item B diverge for the first time. 在二叉搜索树中搜索最低的公共祖先比这简单:观察LCA是第一次搜索项目A和项目B的节点。

Start from the root, and search for A and B at the same time. 从根开始,并同时搜索A和B。 As long as both searches take you in the same direction, continue the search. 只要两次搜索都将您带向同一方向,就可以继续搜索。 Once you arrive at the node such that searching for A and B take you to different subtrees, you know that the current node is the LCA. 到达节点后,通过搜索A和B将您带到不同的子树,您将知道当前节点是LCA。

A node at the bottom of a large binary search trees can have an in-order successor close to it, for instance if it is the left child of a node, its in-order successor is its parent. 大型二叉搜索树底部的节点可以有一个接近的有序后继节点,例如,如果它是节点的左子节点,则它的有序后继节点就是其父节点。

Two nodes descending from different children of the root will have the root as their least common ancestor, no matter where they are, so I believe that your algorithm gets this case wrong. 无论根在哪里,从根的不同子代派生的两个节点都将根作为其最小公祖代,因此我认为您的算法弄错了这种情况。

This is a discussion of efficient LCA algorithms (given time to build a preparatory data structure) at http://en.wikipedia.org/wiki/Lowest_common_ancestor , with pointers to code. http://en.wikipedia.org/wiki/Lowest_common_ancestor上 ,这是对有效LCA算法(给定时间来构建预备数据结构)的讨论,其中包含代码指针。

An inefficient but simple way of finding the LCA is as follows: in the tree keep pointers from children to parents and a note of the depth of each node. 查找LCA的一种低效但简单的方法如下:在树中保留从孩子到父母的指针以及每个节点深度的注释。 Given two nodes, move up from the deepest one until the depth if the same. 给定两个节点,如果深度相同,则从最深的一个向上移动。 If you are pointing at the other node, it is the LCA. 如果您指向另一个节点,则为LCA。 Otherwise move up one step from each node and check again, and so on, until you meet at the LCA. 否则,从每个节点上移一个步骤,然后再次检查,依此类推,直到在LCA见面为止。

Finding LCA of BST is straight: 查找BST的LCA很简单:

Find the node for which node1 and node2 are present on different sides. 查找该节点node1node2存在于不同的侧面。 But if the node1 is an ancestor of node2 than also we will have to return node1 . 但是,如果node1node2的祖先,那么我们还必须返回node1 Below code implements this algo. 下面的代码实现了该算法。


TreeNode<K> commonAncestor(TreeNode t, K k1, K k2){
        if(t==null) return null;
        while(true)
        {
           int c1=t.k.compareTo(k1);
           int c2=t.k.compareTo(k2);
           if(c1*c2<=0)
           {
               return t;
           }
           else
           {
               if(c1<0)
               {
                   t = t.right;
               }
               else
               {
                   t = t.left;
               }
           }
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM