📜  二进制搜索树中的最低共同祖先。

📅  最后修改于: 2021-05-24 22:20:10             🧑  作者: Mango

鉴于两个值的数值N1,并在二叉搜索树N2,发现将L把所欠的Çommon一个ncestor(LCA)。您可以假设这两个值都存在于树中。

例子:

树: BST_LCA输入: 10和14的LCA输出: 12说明: 12是最接近10和14的节点,这是两个节点的祖先。输入: 8和14的LCA输出: 8说明: 8是最接近8和14的节点,这是两个节点的祖先。输入: 10和22的LCA输出: 20说明: 20是最接近10和22的节点,这是两个节点的祖先。

以下是维基百科中LCA的定义:

方法:对于二叉搜索树,从上到下遍历树时,位于两个数字n1和n2之间的第一个节点是节点的LCA,即深度最小的第一个节点n位于n1和n2之间。 n2(n1 <= n <= n2)n1

算法:

  1. 创建一个采用一个节点以及两个值n1和n2的递归函数。
  2. 如果当前节点的值小于n1和n2,则LCA位于右侧子树中。调用右子树的递归函数。
  3. 如果当前节点的值大于n1和n2,则LCA位于左子树中。调用第三个左子树的递归函数。
  4. 如果以上两种情况都为假,则将当前节点作为LCA返回。

执行:

C
// A recursive C program to find LCA of two nodes n1 and n2.
#include 
#include 
  
struct node
{
    int data;
    struct node* left, *right;
};
  
/* Function to find LCA of n1 and n2. The function assumes that both
   n1 and n2 are present in BST */
struct node *lca(struct node* root, int n1, int n2)
{
    if (root == NULL) return NULL;
  
    // If both n1 and n2 are smaller than root, then LCA lies in left
    if (root->data > n1 && root->data > n2)
        return lca(root->left, n1, n2);
  
    // If both n1 and n2 are greater than root, then LCA lies in right
    if (root->data < n1 && root->data < n2)
        return lca(root->right, n1, n2);
  
    return root;
}
  
/* Helper function that allocates a new node with the given data.*/
struct node* newNode(int data)
{
    struct node* node = (struct node*)malloc(sizeof(struct node));
    node->data  = data;
    node->left  = node->right = NULL;
    return(node);
}
  
/* Driver program to test lca() */
int main()
{
    // Let us construct the BST shown in the above figure
    struct node *root        = newNode(20);
    root->left               = newNode(8);
    root->right              = newNode(22);
    root->left->left         = newNode(4);
    root->left->right        = newNode(12);
    root->left->right->left  = newNode(10);
    root->left->right->right = newNode(14);
  
    int n1 = 10, n2 = 14;
    struct node *t = lca(root, n1, n2);
    printf("LCA of %d and %d is %d \n", n1, n2, t->data);
  
    n1 = 14, n2 = 8;
    t = lca(root, n1, n2);
    printf("LCA of %d and %d is %d \n", n1, n2, t->data);
  
    n1 = 10, n2 = 22;
    t = lca(root, n1, n2);
    printf("LCA of %d and %d is %d \n", n1, n2, t->data);
  
    getchar();
    return 0;
}


C++
// A recursive CPP program to find
// LCA of two nodes n1 and n2. 
#include 
using namespace std;
  
class node 
{ 
    public:
    int data; 
    node* left, *right; 
}; 
  
/* Function to find LCA of n1 and n2. 
The function assumes that both 
n1 and n2 are present in BST */
node *lca(node* root, int n1, int n2) 
{ 
    if (root == NULL) return NULL; 
  
    // If both n1 and n2 are smaller
    // than root, then LCA lies in left 
    if (root->data > n1 && root->data > n2) 
        return lca(root->left, n1, n2); 
  
    // If both n1 and n2 are greater than 
    // root, then LCA lies in right 
    if (root->data < n1 && root->data < n2) 
        return lca(root->right, n1, n2); 
  
    return root; 
} 
  
/* Helper function that allocates 
a new node with the given data.*/
node* newNode(int data) 
{ 
    node* Node = new node();
    Node->data = data; 
    Node->left = Node->right = NULL; 
    return(Node); 
} 
  
/* Driver code*/
int main() 
{ 
    // Let us construct the BST 
    // shown in the above figure 
    node *root = newNode(20); 
    root->left = newNode(8); 
    root->right = newNode(22); 
    root->left->left = newNode(4); 
    root->left->right = newNode(12); 
    root->left->right->left = newNode(10); 
    root->left->right->right = newNode(14); 
  
    int n1 = 10, n2 = 14; 
    node *t = lca(root, n1, n2); 
    cout << "LCA of " << n1 << " and " << n2 << " is " << t->data<data << endl; 
  
    n1 = 10, n2 = 22; 
    t = lca(root, n1, n2); 
    cout << "LCA of " << n1 << " and " << n2 << " is " << t->data << endl; 
    return 0; 
} 
  
// This code is contributed by rathbhupendra


Java
// Recursive Java program to print lca of two nodes
   
// A binary tree node
class Node 
{
    int data;
    Node left, right;
   
    Node(int item) 
    {
        data = item;
        left = right = null;
    }
}
   
class BinaryTree 
{
    Node root;
       
    /* Function to find LCA of n1 and n2. The function assumes that both
       n1 and n2 are present in BST */
    Node lca(Node node, int n1, int n2) 
    {
        if (node == null)
            return null;
   
        // If both n1 and n2 are smaller than root, then LCA lies in left
        if (node.data > n1 && node.data > n2)
            return lca(node.left, n1, n2);
   
        // If both n1 and n2 are greater than root, then LCA lies in right
        if (node.data < n1 && node.data < n2) 
            return lca(node.right, n1, n2);
   
        return node;
    }
   
    /* Driver program to test lca() */
    public static void main(String args[]) 
    {
        // Let us construct the BST shown in the above figure
        BinaryTree tree = new BinaryTree();
        tree.root = new Node(20);
        tree.root.left = new Node(8);
        tree.root.right = new Node(22);
        tree.root.left.left = new Node(4);
        tree.root.left.right = new Node(12);
        tree.root.left.right.left = new Node(10);
        tree.root.left.right.right = new Node(14);
   
        int n1 = 10, n2 = 14;
        Node t = tree.lca(tree.root, n1, n2);
        System.out.println("LCA of " + n1 + " and " + n2 + " is " + t.data);
   
        n1 = 14;
        n2 = 8;
        t = tree.lca(tree.root, n1, n2);
        System.out.println("LCA of " + n1 + " and " + n2 + " is " + t.data);
   
        n1 = 10;
        n2 = 22;
        t = tree.lca(tree.root, n1, n2);
        System.out.println("LCA of " + n1 + " and " + n2 + " is " + t.data);
   
    }
}
   
// This code has been contributed by Mayank Jaiswal


Python
# A recursive python program to find LCA of two nodes
# n1 and n2
  
# A Binary tree node
class Node:
  
    # Constructor to create a new node
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
  
# Function to find LCA of n1 and n2. The function assumes
# that both n1 and n2 are present in BST
def lca(root, n1, n2):
      
    # Base Case
    if root is None:
        return None
  
    # If both n1 and n2 are smaller than root, then LCA
    # lies in left
    if(root.data > n1 and root.data > n2):
        return lca(root.left, n1, n2)
  
    # If both n1 and n2 are greater than root, then LCA
    # lies in right 
    if(root.data < n1 and root.data < n2):
        return lca(root.right, n1, n2)
  
    return root
  
# Driver program to test above function
  
# Let us construct the BST shown in the figure
root = Node(20)
root.left = Node(8)
root.right = Node(22)
root.left.left = Node(4)
root.left.right = Node(12)
root.left.right.left = Node(10)
root.left.right.right = Node(14)
  
n1 = 10 ; n2 = 14
t = lca(root, n1, n2)
print "LCA of %d and %d is %d" %(n1, n2, t.data)
  
n1 = 14 ; n2 = 8
t = lca(root, n1, n2)
print "LCA of %d and %d is %d" %(n1, n2 , t.data)
  
n1 = 10 ; n2 = 22
t = lca(root, n1, n2)
print "LCA of %d and %d is %d" %(n1, n2, t.data)
  
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)


C#
using System;
  
// Recursive C#  program to print lca of two nodes 
  
// A binary tree node 
public class Node
{
    public int data;
    public Node left, right;
  
    public Node(int item)
    {
        data = item;
        left = right = null;
    }
}
  
public class BinaryTree
{
    public Node root;
  
    /* Function to find LCA of n1 and n2. The function assumes that both 
       n1 and n2 are present in BST */
    public virtual Node lca(Node node, int n1, int n2)
    {
        if (node == null)
        {
            return null;
        }
  
        // If both n1 and n2 are smaller than root, then LCA lies in left 
        if (node.data > n1 && node.data > n2)
        {
            return lca(node.left, n1, n2);
        }
  
        // If both n1 and n2 are greater than root, then LCA lies in right 
        if (node.data < n1 && node.data < n2)
        {
            return lca(node.right, n1, n2);
        }
  
        return node;
    }
  
    /* Driver program to test lca() */
    public static void Main(string[] args)
    {
        // Let us construct the BST shown in the above figure 
        BinaryTree tree = new BinaryTree();
        tree.root = new Node(20);
        tree.root.left = new Node(8);
        tree.root.right = new Node(22);
        tree.root.left.left = new Node(4);
        tree.root.left.right = new Node(12);
        tree.root.left.right.left = new Node(10);
        tree.root.left.right.right = new Node(14);
  
        int n1 = 10, n2 = 14;
        Node t = tree.lca(tree.root, n1, n2);
        Console.WriteLine("LCA of " + n1 + " and " + n2 + " is " + t.data);
  
        n1 = 14;
        n2 = 8;
        t = tree.lca(tree.root, n1, n2);
        Console.WriteLine("LCA of " + n1 + " and " + n2 + " is " + t.data);
  
        n1 = 10;
        n2 = 22;
        t = tree.lca(tree.root, n1, n2);
        Console.WriteLine("LCA of " + n1 + " and " + n2 + " is " + t.data);
  
    }
}
  
  //  This code is contributed by Shrikant13


C
// A recursive C program to find LCA of two nodes n1 and n2.
#include 
#include 
  
struct node
{
    int data;
    struct node* left, *right;
};
  
/* Function to find LCA of n1 and n2. The function assumes that both
n1 and n2 are present in BST */
struct node *lca(struct node* root, int n1, int n2)
{
    while (root != NULL)
    {
        // If both n1 and n2 are smaller than root, then LCA lies in left
        if (root->data > n1 && root->data > n2)
        root = root->left;
  
        // If both n1 and n2 are greater than root, then LCA lies in right
        else if (root->data < n1 && root->data < n2)
        root = root->right;
  
        else break;
    }
    return root;
}
  
  
/* Helper function that allocates a new node with the given data.*/
struct node* newNode(int data)
{
    struct node* node = (struct node*)malloc(sizeof(struct node));
    node->data = data;
    node->left = node->right = NULL;
    return(node);
}
  
/* Driver program to test lca() */
int main()
{
    // Let us construct the BST shown in the above figure
    struct node *root     = newNode(20);
    root->left             = newNode(8);
    root->right             = newNode(22);
    root->left->left         = newNode(4);
    root->left->right     = newNode(12);
    root->left->right->left = newNode(10);
    root->left->right->right = newNode(14);
  
    int n1 = 10, n2 = 14;
    struct node *t = lca(root, n1, n2);
    printf("LCA of %d and %d is %d \n", n1, n2, t->data);
  
    n1 = 14, n2 = 8;
    t = lca(root, n1, n2);
    printf("LCA of %d and %d is %d \n", n1, n2, t->data);
  
    n1 = 10, n2 = 22;
    t = lca(root, n1, n2);
    printf("LCA of %d and %d is %d \n", n1, n2, t->data);
  
    getchar();
    return 0;
}


C++
// A recursive CPP program to find
// LCA of two nodes n1 and n2. 
#include 
using namespace std;
  
class node 
{ 
    public:
    int data; 
    node* left, *right; 
}; 
  
/* Function to find LCA of n1 and n2. 
The function assumes that both n1 and n2
are present in BST */
struct node *lca(struct node* root, int n1, int n2)
{
    while (root != NULL)
    {
        // If both n1 and n2 are smaller than root,
        // then LCA lies in left
        if (root->data > n1 && root->data > n2)
        root = root->left;
  
        // If both n1 and n2 are greater than root, 
        // then LCA lies in right
        else if (root->data < n1 && root->data < n2)
        root = root->right;
  
        else break;
    }
    return root;
}
   
  
/* Helper function that allocates 
a new node with the given data.*/
node* newNode(int data) 
{ 
    node* Node = new node();
    Node->data = data; 
    Node->left = Node->right = NULL; 
    return(Node); 
} 
  
/* Driver code*/
int main() 
{ 
    // Let us construct the BST 
    // shown in the above figure 
    node *root = newNode(20); 
    root->left = newNode(8); 
    root->right = newNode(22); 
    root->left->left = newNode(4); 
    root->left->right = newNode(12); 
    root->left->right->left = newNode(10); 
    root->left->right->right = newNode(14); 
  
    int n1 = 10, n2 = 14; 
    node *t = lca(root, n1, n2); 
    cout << "LCA of " << n1 << " and " << n2 << " is " << t->data<data << endl; 
  
    n1 = 10, n2 = 22; 
    t = lca(root, n1, n2); 
    cout << "LCA of " << n1 << " and " << n2 << " is " << t->data << endl; 
    return 0; 
} 
  
// This code is contributed by rathbhupendra


Java
// Recursive Java program to print lca of two nodes
  
// A binary tree node
class Node 
{
    int data;
    Node left, right;
  
    Node(int item) 
    {
        data = item;
        left = right = null;
    }
}
  
class BinaryTree 
{
    Node root;
      
/* Function to find LCA of n1 and n2. 
The function assumes that both 
n1 and n2 are present in BST */
static Node lca(Node root, int n1, int n2) 
{ 
    while (root != null) 
    { 
        // If both n1 and n2 are smaller 
        // than root, then LCA lies in left 
        if (root.data > n1 && 
            root.data > n2) 
        root = root.left; 
  
        // If both n1 and n2 are greater 
        // than root, then LCA lies in right 
        else if (root.data < n1 && 
                 root.data < n2) 
        root = root.right; 
  
        else break; 
    } 
    return root; 
} 
  
  
    /* Driver program to test lca() */
    public static void main(String args[]) 
    {
        // Let us construct the BST shown in the above figure
        BinaryTree tree = new BinaryTree();
        tree.root = new Node(20);
        tree.root.left = new Node(8);
        tree.root.right = new Node(22);
        tree.root.left.left = new Node(4);
        tree.root.left.right = new Node(12);
        tree.root.left.right.left = new Node(10);
        tree.root.left.right.right = new Node(14);
  
        int n1 = 10, n2 = 14;
        Node t = tree.lca(tree.root, n1, n2);
        System.out.println("LCA of " + n1 + " and " + n2 + " is " + t.data);
  
        n1 = 14;
        n2 = 8;
        t = tree.lca(tree.root, n1, n2);
        System.out.println("LCA of " + n1 + " and " + n2 + " is " + t.data);
  
        n1 = 10;
        n2 = 22;
        t = tree.lca(tree.root, n1, n2);
        System.out.println("LCA of " + n1 + " and " + n2 + " is " + t.data);
  
    }
}
// This code is contributed by SHUBHAMSINGH10


Python
# A recursive python program to find LCA of two nodes
# n1 and n2
  
# A Binary tree node
class Node:
  
    # Constructor to create a new node
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
  
# Function to find LCA of n1 and n2. 
# The function assumes that both
#   n1 and n2 are present in BST 
def lca(root, n1, n2):
    while root:
        # If both n1 and n2 are smaller than root,
        # then LCA lies in left
        if root.data > n1 and root.data > n2:
            root = root.left
          
        # If both n1 and n2 are greater than root, 
        # then LCA lies in right
        elif root.data < n1 and root.data < n2:
            root = root.right
  
        else:
            break
  
    return root
  
# Driver program to test above function
# Let us construct the BST shown in the figure
root = Node(20)
root.left = Node(8)
root.right = Node(22)
root.left.left = Node(4)
root.left.right = Node(12)
root.left.right.left = Node(10)
root.left.right.right = Node(14)
  
n1 = 10 ; n2 = 14
t = lca(root, n1, n2)
print "LCA of %d and %d is %d" %(n1, n2, t.data)
  
n1 = 14 ; n2 = 8
t = lca(root, n1, n2)
print "LCA of %d and %d is %d" %(n1, n2 , t.data)
  
n1 = 10 ; n2 = 22
t = lca(root, n1, n2)
print "LCA of %d and %d is %d" %(n1, n2, t.data)
# This Code is Contributed by Sumit Bhardwaj (Timus)


C#
using System;
  
// Recursive C# program to print lca of two nodes 
  
// A binary tree node 
public class Node
{
    public int data;
    public Node left, right;
  
    public Node(int item)
    {
        data = item;
        left = right = null;
    }
}
  
public class BinaryTree
{
    public Node root;
  
/* Function to find LCA of n1 and n2.
The function assumes that both 
n1 and n2 are present in BST */
public virtual Node lca(Node root, int n1, int n2) 
{ 
    while (root != null) 
    { 
        // If both n1 and n2 are smaller than
        // root, then LCA lies in left 
        if (root.data > n1 && root.data > n2) 
        root = root.left; 
   
        // If both n1 and n2 are greater than 
        // root, then LCA lies in right 
        else if (root.data < n1 && root.data < n2) 
        root = root.right; 
   
        else break; 
    } 
    return root; 
} 
  
    /* Driver program to test lca() */
    public static void Main(string[] args)
    {
        // Let us construct the BST shown in the above figure 
        BinaryTree tree = new BinaryTree();
        tree.root = new Node(20);
        tree.root.left = new Node(8);
        tree.root.right = new Node(22);
        tree.root.left.left = new Node(4);
        tree.root.left.right = new Node(12);
        tree.root.left.right.left = new Node(10);
        tree.root.left.right.right = new Node(14);
  
        int n1 = 10, n2 = 14;
        Node t = tree.lca(tree.root, n1, n2);
        Console.WriteLine(
            "LCA of " + n1 + " and " + n2
            + " is " + t.data);
  
        n1 = 14;
        n2 = 8;
        t = tree.lca(tree.root, n1, n2);
        Console.WriteLine(
            "LCA of " + n1 + " and " + n2
            + " is " + t.data);
  
        n1 = 10;
        n2 = 22;
        t = tree.lca(tree.root, n1, n2);
        Console.WriteLine(
            "LCA of " + n1 + " and " + n2 
            + " is " + t.data);
    }
}
  
// This code is contributed by Shrikant13


输出:

LCA of 10 and 14 is 12
LCA of 14 and 8 is 8
LCA of 10 and 22 is 20

复杂度分析:

  • 时间复杂度: O(h)。
    上述解决方案的时间复杂度为O(h),其中h是树的高度。
  • 空间复杂度: O(1)。
    如果忽略递归堆栈空间,则上述解决方案的空间复杂度是恒定的。

迭代实现:上面的解决方案使用递归。递归解决方案需要以函数调用堆栈的形式提供额外的空间。因此,可以实现一种迭代解决方案,该解决方案不会以函数调用堆栈的形式占用空间。

执行:

C

// A recursive C program to find LCA of two nodes n1 and n2.
#include 
#include 
  
struct node
{
    int data;
    struct node* left, *right;
};
  
/* Function to find LCA of n1 and n2. The function assumes that both
n1 and n2 are present in BST */
struct node *lca(struct node* root, int n1, int n2)
{
    while (root != NULL)
    {
        // If both n1 and n2 are smaller than root, then LCA lies in left
        if (root->data > n1 && root->data > n2)
        root = root->left;
  
        // If both n1 and n2 are greater than root, then LCA lies in right
        else if (root->data < n1 && root->data < n2)
        root = root->right;
  
        else break;
    }
    return root;
}
  
  
/* Helper function that allocates a new node with the given data.*/
struct node* newNode(int data)
{
    struct node* node = (struct node*)malloc(sizeof(struct node));
    node->data = data;
    node->left = node->right = NULL;
    return(node);
}
  
/* Driver program to test lca() */
int main()
{
    // Let us construct the BST shown in the above figure
    struct node *root     = newNode(20);
    root->left             = newNode(8);
    root->right             = newNode(22);
    root->left->left         = newNode(4);
    root->left->right     = newNode(12);
    root->left->right->left = newNode(10);
    root->left->right->right = newNode(14);
  
    int n1 = 10, n2 = 14;
    struct node *t = lca(root, n1, n2);
    printf("LCA of %d and %d is %d \n", n1, n2, t->data);
  
    n1 = 14, n2 = 8;
    t = lca(root, n1, n2);
    printf("LCA of %d and %d is %d \n", n1, n2, t->data);
  
    n1 = 10, n2 = 22;
    t = lca(root, n1, n2);
    printf("LCA of %d and %d is %d \n", n1, n2, t->data);
  
    getchar();
    return 0;
}

C++

// A recursive CPP program to find
// LCA of two nodes n1 and n2. 
#include 
using namespace std;
  
class node 
{ 
    public:
    int data; 
    node* left, *right; 
}; 
  
/* Function to find LCA of n1 and n2. 
The function assumes that both n1 and n2
are present in BST */
struct node *lca(struct node* root, int n1, int n2)
{
    while (root != NULL)
    {
        // If both n1 and n2 are smaller than root,
        // then LCA lies in left
        if (root->data > n1 && root->data > n2)
        root = root->left;
  
        // If both n1 and n2 are greater than root, 
        // then LCA lies in right
        else if (root->data < n1 && root->data < n2)
        root = root->right;
  
        else break;
    }
    return root;
}
   
  
/* Helper function that allocates 
a new node with the given data.*/
node* newNode(int data) 
{ 
    node* Node = new node();
    Node->data = data; 
    Node->left = Node->right = NULL; 
    return(Node); 
} 
  
/* Driver code*/
int main() 
{ 
    // Let us construct the BST 
    // shown in the above figure 
    node *root = newNode(20); 
    root->left = newNode(8); 
    root->right = newNode(22); 
    root->left->left = newNode(4); 
    root->left->right = newNode(12); 
    root->left->right->left = newNode(10); 
    root->left->right->right = newNode(14); 
  
    int n1 = 10, n2 = 14; 
    node *t = lca(root, n1, n2); 
    cout << "LCA of " << n1 << " and " << n2 << " is " << t->data<data << endl; 
  
    n1 = 10, n2 = 22; 
    t = lca(root, n1, n2); 
    cout << "LCA of " << n1 << " and " << n2 << " is " << t->data << endl; 
    return 0; 
} 
  
// This code is contributed by rathbhupendra

Java

// Recursive Java program to print lca of two nodes
  
// A binary tree node
class Node 
{
    int data;
    Node left, right;
  
    Node(int item) 
    {
        data = item;
        left = right = null;
    }
}
  
class BinaryTree 
{
    Node root;
      
/* Function to find LCA of n1 and n2. 
The function assumes that both 
n1 and n2 are present in BST */
static Node lca(Node root, int n1, int n2) 
{ 
    while (root != null) 
    { 
        // If both n1 and n2 are smaller 
        // than root, then LCA lies in left 
        if (root.data > n1 && 
            root.data > n2) 
        root = root.left; 
  
        // If both n1 and n2 are greater 
        // than root, then LCA lies in right 
        else if (root.data < n1 && 
                 root.data < n2) 
        root = root.right; 
  
        else break; 
    } 
    return root; 
} 
  
  
    /* Driver program to test lca() */
    public static void main(String args[]) 
    {
        // Let us construct the BST shown in the above figure
        BinaryTree tree = new BinaryTree();
        tree.root = new Node(20);
        tree.root.left = new Node(8);
        tree.root.right = new Node(22);
        tree.root.left.left = new Node(4);
        tree.root.left.right = new Node(12);
        tree.root.left.right.left = new Node(10);
        tree.root.left.right.right = new Node(14);
  
        int n1 = 10, n2 = 14;
        Node t = tree.lca(tree.root, n1, n2);
        System.out.println("LCA of " + n1 + " and " + n2 + " is " + t.data);
  
        n1 = 14;
        n2 = 8;
        t = tree.lca(tree.root, n1, n2);
        System.out.println("LCA of " + n1 + " and " + n2 + " is " + t.data);
  
        n1 = 10;
        n2 = 22;
        t = tree.lca(tree.root, n1, n2);
        System.out.println("LCA of " + n1 + " and " + n2 + " is " + t.data);
  
    }
}
// This code is contributed by SHUBHAMSINGH10

Python

# A recursive python program to find LCA of two nodes
# n1 and n2
  
# A Binary tree node
class Node:
  
    # Constructor to create a new node
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
  
# Function to find LCA of n1 and n2. 
# The function assumes that both
#   n1 and n2 are present in BST 
def lca(root, n1, n2):
    while root:
        # If both n1 and n2 are smaller than root,
        # then LCA lies in left
        if root.data > n1 and root.data > n2:
            root = root.left
          
        # If both n1 and n2 are greater than root, 
        # then LCA lies in right
        elif root.data < n1 and root.data < n2:
            root = root.right
  
        else:
            break
  
    return root
  
# Driver program to test above function
# Let us construct the BST shown in the figure
root = Node(20)
root.left = Node(8)
root.right = Node(22)
root.left.left = Node(4)
root.left.right = Node(12)
root.left.right.left = Node(10)
root.left.right.right = Node(14)
  
n1 = 10 ; n2 = 14
t = lca(root, n1, n2)
print "LCA of %d and %d is %d" %(n1, n2, t.data)
  
n1 = 14 ; n2 = 8
t = lca(root, n1, n2)
print "LCA of %d and %d is %d" %(n1, n2 , t.data)
  
n1 = 10 ; n2 = 22
t = lca(root, n1, n2)
print "LCA of %d and %d is %d" %(n1, n2, t.data)
# This Code is Contributed by Sumit Bhardwaj (Timus)

C#

using System;
  
// Recursive C# program to print lca of two nodes 
  
// A binary tree node 
public class Node
{
    public int data;
    public Node left, right;
  
    public Node(int item)
    {
        data = item;
        left = right = null;
    }
}
  
public class BinaryTree
{
    public Node root;
  
/* Function to find LCA of n1 and n2.
The function assumes that both 
n1 and n2 are present in BST */
public virtual Node lca(Node root, int n1, int n2) 
{ 
    while (root != null) 
    { 
        // If both n1 and n2 are smaller than
        // root, then LCA lies in left 
        if (root.data > n1 && root.data > n2) 
        root = root.left; 
   
        // If both n1 and n2 are greater than 
        // root, then LCA lies in right 
        else if (root.data < n1 && root.data < n2) 
        root = root.right; 
   
        else break; 
    } 
    return root; 
} 
  
    /* Driver program to test lca() */
    public static void Main(string[] args)
    {
        // Let us construct the BST shown in the above figure 
        BinaryTree tree = new BinaryTree();
        tree.root = new Node(20);
        tree.root.left = new Node(8);
        tree.root.right = new Node(22);
        tree.root.left.left = new Node(4);
        tree.root.left.right = new Node(12);
        tree.root.left.right.left = new Node(10);
        tree.root.left.right.right = new Node(14);
  
        int n1 = 10, n2 = 14;
        Node t = tree.lca(tree.root, n1, n2);
        Console.WriteLine(
            "LCA of " + n1 + " and " + n2
            + " is " + t.data);
  
        n1 = 14;
        n2 = 8;
        t = tree.lca(tree.root, n1, n2);
        Console.WriteLine(
            "LCA of " + n1 + " and " + n2
            + " is " + t.data);
  
        n1 = 10;
        n2 = 22;
        t = tree.lca(tree.root, n1, n2);
        Console.WriteLine(
            "LCA of " + n1 + " and " + n2 
            + " is " + t.data);
    }
}
  
// This code is contributed by Shrikant13

复杂度分析:

  • 时间复杂度: O(h)。
    上述解决方案的时间复杂度为O(h),其中h是树的高度。
  • 空间复杂度: O(1)。
    上述解决方案的空间复杂度是恒定的。

您可能还希望看到以下文章:

  • 二叉树中的最低共同祖先

  • 使用父指针的LCA

  • 使用RMQ在二叉树中查找LCA

锻炼
上面的函数假定n1和n2都在BST中。如果n1和n2不存在,则它们可能返回不正确的结果。如果n1或n2或两者都不存在于BST中,则扩展上述解决方案以返回NULL。