Given a bst with integer values as keys how do I find the closest node to that key in a bst ? The BST is represented using a object of nodes (Java). Closest will be for eg 4
This can be done using a Queue and a ArrayList. Queue will be used to perform a breadth first search on the tree. ArrayList will be used to store the element of the tree in breadth first order. Here is the code to implement the same
Queue queue = new LinkedList();
ArrayList list = new ArrayList();
int i =0;
public Node findNextRightNode(Node root,int key)
{
System.out.print("The breadth first search on Tree : \t");
if(root == null)
return null;
queue.clear();
queue.add(root);
while(!queue.isEmpty() )
{
Node node = (Node)queue.remove();
System.out.print(node.data + " ");
list.add(node);
if(node.left != null) queue.add(node.left);
if(node.right !=null) queue.add(node.right);
}
Iterator iter = list.iterator();
while(iter.hasNext())
{
if(((Node)iter.next()).data == key)
{
return ((Node)iter.next());
}
}
return null;
}
The problem with the approach "left right traversal and finding the closest" is that it depends over the sequence in which elements were entered to create BST. If we search 11 for the BST sequence 22, 15, 16, 6,14,3,1,90, the above method will return 15 while the correct answer is 14. The only method should be using recursion to traverse all the nodes, returning the closest one as the result of the recursive function. This'll give us the closest value
Here's a recursive solution in Python:
def searchForClosestNodeHelper(root, val, closestNode):
if root is None:
return closestNode
if root.val == val:
return root
if closestNode is None or abs(root.val - val) < abs(closestNode.val - val):
closestNode = root
if val < root.val:
return searchForClosestNodeHelper(root.left, val, closestNode)
else:
return searchForClosestNodeHelper(root.right, val, closestNode)
def searchForClosestNode(root, val):
return searchForClosestNodeHelper(root, val, None)
Here is the full Java code to find the closest element in a BST.
package binarytree;
class BSTNode {
BSTNode left,right;
int data;
public BSTNode(int data) {
this.data = data;
this.left = this.right = null;
}
}
class BST {
BSTNode root;
public static BST createBST() {
BST bst = new BST();
bst.root = new BSTNode(9);
bst.root.left = new BSTNode(4);
bst.root.right = new BSTNode(17);
bst.root.left.left = new BSTNode(3);
bst.root.left.right= new BSTNode(6);
bst.root.left.right.left= new BSTNode(5);
bst.root.left.right.right= new BSTNode(7);
bst.root.right.right = new BSTNode(22);
bst.root.right.right.left = new BSTNode(20);
return bst;
}
}
public class ClosestElementInBST {
public static void main(String[] args) {
BST bst = BST.createBST();
int target = 18;
BSTNode currentClosest = null;
BSTNode closestNode = findClosestElement(bst.root, target, currentClosest);
if(closestNode != null) {
System.out.println("Found closest node: " + closestNode.data);
}
else {
System.out.println("Couldn't find closest node.");
}
}
private static BSTNode findClosestElement(BSTNode node, int target, BSTNode currentClosest) {
if(node == null) return currentClosest;
if(currentClosest == null ||
(currentClosest != null && (Math.abs(currentClosest.data - target) > Math.abs(node.data - target)))) {
currentClosest = node;
}
if(node.data == target) return node;
else if(target < node.data) {
return findClosestElement(node.left, target, currentClosest);
}
else { //target > node.data
currentClosest = node;
return findClosestElement(node.right, target, currentClosest);
}
}
}