import java.util.NoSuchElementException; public class BinarySearchTree< E extends Comparable > { // A static nested class used to store the elements of this tree private static class Node { private E value; private Node left; private Node right; private Node( E value ) { this.value = value; left = null; right = null; } } private Node root = null; /** * Inserts an object into this BinarySearchTree. * * @param obj item to be added * @return true if the object has been added and false otherwise */ public boolean add( E obj ) { // pre-condtion: if ( obj == null ) { throw new IllegalArgumentException( "null" ); } // special case: if ( root == null ) { root = new Node( obj ); return true; } // general case: return add( obj, root ); } private boolean add( E obj, Node current ) { boolean result; int test = obj.compareTo( current.value ); if ( test == 0 ) { result = false; } else if ( test < 0 ) { if ( current.left == null ) { current.left = new Node( obj ); result = true; } else { result = add( obj, current.left ); } } else { if ( current.right == null ) { current.right = new Node( obj ); result = true; } else { result = add( obj, current.right ); } } return result; } /** * Looks up for obj in this BinarySearchTree, returns true * if obj is found and false otherwise. * * @param obj value to look for * @return true if the object has been found and false otherwise */ public boolean contains( E obj ) { // pre-condtion: if ( obj == null ) { throw new IllegalArgumentException( "null" ); } return contains( obj, root ); } private boolean contains( E obj, Node current ) { boolean result; if ( current == null ) { result = false; } else { int test = obj.compareTo( current.value ); if ( test == 0 ) { result = true; } else if ( test < 0 ) { result = contains( obj, current.left ); } else { result = contains( obj, current.right ); } } return result; } public E max() { if ( root == null ) { throw new NoSuchElementException(); } return max( root ); } private E max( Node current ) { if ( current.right == null ) { return current.value; } else { return max( current.right ); } } public E min() { if ( root == null ) { throw new NoSuchElementException(); } return min( root ); } private E min( Node current ) { if ( current.left == null ) { return current.value; } else { return min( current.left ); } } public boolean isTwoTree() { return isTwoTree( root ); } private boolean isTwoTree( Node current ) { boolean answer; if ( current == null ) { answer = true; } else { if ( current.left == null || current.right == null ) { answer = current.left == null && current.right == null; } else { answer = isTwoTree( current.left ) && isTwoTree( current.right ); } } return answer; } public int depth() { return depth( root ); } private int depth( Node current ) { if ( current == null ) { return -1; } else { int dleft, dright; dleft = depth( current.left ); dright = depth( current.right ); return Math.max( dleft, dright ) + 1; } } private static String NL = System.getProperty( "line.separator" ); public String toString() { return toString( root, "" ); } private String toString( Node current, String padding ) { String result; if ( current == null ) { result = padding + "null" + NL; } else { result = toString( current.right, padding + " " ); result += padding + current.value + NL; result += toString( current.left, padding + " " ); } return result; } }