public class BST<Key extends Comparable<Key>, Value>
{
   private Node root;

   private class Node
   {
      private Key key;
      private Value val;
      private Node left, right;

      Node(Key key, Value val)
      {
         this.key = key;
         this.val = val;
      }
   }

   public Value search(Key key)
   {
      Node x = root;

      while (x != null)
      {
         int cmp = key.compareTo(x.key);

         if (cmp == 0) 
            return x.val;
         else if (cmp < 0) 
            x = x.left;
         else if (cmp > 0) 
            x = x.right;
      }
      return null;
   }

   /* ==============================================
      Main insert method
      ============================================== */
   public void insert(Key key, Value value)
   {
      root = insert(root, key, value);
   }

   /* ==============================================
      HELPER insert method (recursive)

          h = root node of the subtree

      Insert (key, value) in subtree at root h
      Return the new tree after insertion
      ============================================== */
   private Node insert(Node h, Key key, Value value)
   {
      if (h == null) 
         return new Node(key, value);

      /* -------------------------------------
         This is the BST insert alg.
         ------------------------------------- */

      int cmp = key.compareTo(h.key);

      if (cmp == 0) 
         h.val = value;  // Found, update value
      else if (cmp < 0) 
         h.left = insert(h.left, key, value);   // insert (key, value) in left
      else 
         h.right = insert(h.right, key, value); // insert (key, value) in right

      return h;
   }

}