To find the Lowest Common Ancestor of node A and node B do
Example: We have to find the lowest common ancestor of node 1 and node 13.
As we recurse downwards in the left-subtree, data of the leaf node 1 matches with the data of node 1, hence
Similary As we recurse downwards, data of the leaf node 13 matches with the data of node 13, hence
Note: Data of leaf nodes 7, 12 and 20 doesn’t match with the data of node 1 or node 13 hence each returns Null to the parent.
As the left sub-tree and the right sub-tree of the root (9) has node 1 and node 13 respectively, root (9) has to be the lowest common ancestor of node 1 and node 13.
Algorithm: GetLCA ( Root, Node A, Node B )
If ( Root == Null or Root.Data == (Node A).Data or
Root.Data == (Node B).Data ) then
return Root
LCA_From_Left = GetLCA ( Root.Left, Node A, Node B )
LCA_From_Right = GetLCA ( Root.Right, Node A, Node B )
If (LCA_From_Left != Null and LCA_From_Right != Null ) then
return Root
If ( LCA_From_Left == Null )
return LCA_From_Right
Else
return LCA_From_Left
Time complexity : O ( N ), where ‘N’ is the number of nodes in the tree. As this algorithm uses tree traversal like post-order where every node is visited only once, it gives us the time complexity of O ( N ).
Program for recursively finding the Lowest Common Ancestor (LCA) in a binary tree
#include <iostream>
#include <stack>
using namespace std;
class Node{
public:
Node(int n): data(n), left(nullptr), right(nullptr) { }
Node(int n, Node * arg_left, Node * arg_right): data(n), left(arg_left), right(arg_right) { }
Node * left;
Node * right;
int data;
};
Node * GetLCA (Node * root, Node * p, Node * q) {
if (root == nullptr || root->data == p->data || root->data == q->data)
return root;
Node * left_lca = GetLCA (root->left, p, q);
Node * right_lca = GetLCA (root->right, p, q);
if (left_lca && right_lca)
return root;
if (left_lca == NULL)
return right_lca;
else
return left_lca;
}
/* Constructed binary tree is
9
/ \
5 16
/ \ / \
3 7 12 18
/ / \
1 15 20
/
13
*/
int main() {
Node node_1(1, nullptr, nullptr);
Node node_7(7, nullptr, nullptr);
Node node_12(12, nullptr, nullptr);
Node node_13(13, nullptr, nullptr);
Node node_20(20, nullptr, nullptr);
Node node_15(15, &node_13, nullptr);
Node node_3(3, &node_1, nullptr);
Node node_18(18, &node_15, &node_20);
Node node_5(5, &node_3, &node_7);
Node node_16(16, &node_12, &node_18);
Node root(9, &node_5, &node_16);
cout << "LCA of (1, 13) : " << GetLCA(&root, &node_1, &node_13)->data << endl;
cout << "LCA of (3, 7) : " << GetLCA(&root, &node_3, &node_7)->data << endl;
cout << "LCA of (12, 20) : " << GetLCA(&root, &node_12, &node_20)->data << endl;
cout << "LCA of (15, 18) : " << GetLCA(&root, &node_15, &node_18)->data << endl;
return 0;
}
Output
LCA of (1, 13) : 9
LCA of (3, 7) : 5
LCA of (12, 20) : 16
LCA of (15, 18) : 18