Question is from here.
Given a binary search tree (BST), find the lowest common ancestor of two given nodes in the BST.
_______6______ / \ ___2__ ___8__ / \ / \ 0 _4 7 9 / \ 3 5
According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes vand w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).” Since a node can be a descendant of itself, the LCA of 2 and 4 should be 2, according to this definition.
Here is my solution:
C++:(recursively) add the following code into my C++ BST class:
Vertex * FindVertex(elem_t E)
{
while(Root != NULL)
{
if( Root->Elem == E) return Root;
if( Root->Elem > E)
Root = Root->Left;
else if( Root ->Elem < E)
Root = Root->Right;
}
return NULL;
}
Vertex *LCA(Vertex *root, elem_t p, elem_t q)
{
if (!root) return NULL;
if (p < root->Elem && q < root->Elem)
return LCA(root->Left, p, q);
else if (p > root->Elem && q > root->Elem)
return LCA(root->Right, p, q);
else
return root;
}
Vertex *LCA(Vertex *root, Vertex *p, Vertex *q)
{
if (!root || !p || !q) return NULL;
return LCA(root,p->Elem, q->Elem);
}
void PrintVertex(Vertex *V)
{
if(!V)
cout<<"The value of this vertex is: NULL"<<endl;
cout<<"The value of this vertex is: "<< V->Elem<<endl;
}
should add another method called contains(int, Vertex) to check if those values are in the tree/subtree.
TEST: add in main:
//Test for LCA
Vertex *P = newTest.FindVertex(7);
//if( contains(1,P)&& contains(10, P))
//right now, if one vertex is not in the subtree, LCA will return the P(subtree root).
Vertex *V = newTest.LCA(P,1,10);
newTest.PrintVertex(V);
Vertex *P1 = newTest.FindVertex(9);
Vertex *V1 = newTest.LCA(P1,1,10);
newTest.PrintVertex(V1);
Java: (Iteratively) add the code into the Java BinarySearchTree class:
public BinaryNode<AnyType> find(AnyType x, BinaryNode<AnyType> t)
{
if( t == null) return null;
int compareResult = x.compareTo(t.element);
if(compareResult == 0) return t;
if(compareResult < 0)
return find(x,t.left);
else if(compareResult > 0)
return find(x,t.right);
return null;
}
public BinaryNode<AnyType> LCA(BinaryNode<AnyType> root, AnyType P, AnyType Q)
{
if ( !contains(P, root) || !contains(Q, root)) return null;
while( root != null)
{
int compareP = P.compareTo(root.element);
int compareQ = Q.compareTo(root.element);
if( compareP > 0 && compareQ > 0 )
root = root.right;
else if( compareP < 0 && compareQ < 0)
root = root.left;
else
return root;
}
return null;
}
public BinaryNode<AnyType> LCA(BinaryNode<AnyType> root, BinaryNode<AnyType> P, BinaryNode<AnyType> Q)
{
if( root == null || P == null || Q == null ) return null;
return LCA(root, P.element, Q.element);
}
public void PrintNode(BinaryNode<AnyType> t)
{
if( t== null )
System.out.println("The element is: null");
else
System.out.println("The element is: " + t.element);
}
Test: in main:
BinarySearchTree<Integer> newTest = new BinarySearchTree<>( );
newTest.insert(7); // root
newTest.insert(1); // level 1 L
newTest.insert(2); // level 2 R
newTest.insert(0); // level 2 L
newTest.insert(5); // level 3 R
newTest.insert(6); //level 4 R
newTest.insert(9); // level 2 R
newTest.insert(4); // level 4 L
newTest.insert(10); // level 3 R
newTest.insert(8); //level 3 L
newTest.printTree();
//Test for LCA
newTest.PrintNode( newTest.LCA(newTest.find(7),1,10));
BinaryNode<Integer> t = newTest.find(9);
BinaryNode<Integer> n1 = newTest.LCA(t,1,10);
newTest.PrintNode(n1 );
Result:
0
1
2
4
5
6
7
8
9
10
The element is: 7
The element is: null