package rebelsky.dict; import java.util.Comparator; /** * A simple and partial implementation of binary search trees. * * @author Samuel A. Rebelsky * @version 1.0 of November 2004 */ public class BST { // +-------+--------------------------------------------------- // | Notes | // +-------+ /* (1) The tree is implemented using BSTNodes. (2) To handle the problem of deciding when to insert a node, we use the trick of having insert return a node. (If the node is already there, insert returns the same node. If there is no node, it creates one.) */ // +--------+-------------------------------------------------- // | Fields | // +--------+ /** * The root of the tree. */ BSTNode root; /** * The comparator used to determine order. */ Comparator c; // +--------------+-------------------------------------------- // | Constructors | // +--------------+ /** * Build a new BST that uses a particular comparator * to order objects. */ public BST(Comparator _c) { this.c = _c; } // BST(Object) // +----------------+------------------------------------------ // | Public Methods | // +----------------+ /** * Insert an object into the tree. * * @pre * The object must be a valid parameter for the tree's * comparator. */ public void insert(Object insertMe) { this.root = this.insert(this.root, insertMe); } // insert(Object) /** * Find an object equal to findMe in the tree. * * @pre * The object must be a valid parameter for the tree's * comparator. * @post * If the tree contains an object, o, such that * c.compare(o, findMe) is 0, returns that object. * @exception NotFound * If no such object can be found. */ public Object find(Object findMe) throws NotFound { return find(this.root, findMe); } // find(Object) // +-----------------+----------------------------------------- // | Private Methods | // +-----------------+ /** * Insert a value into the subtree rooted at here. */ public BSTNode insert(BSTNode here, Object insertMe) { // First case: There is no subtree. Create one. if (here == null) return new BSTNode(insertMe); // Second case: Less than or equal to the root value. // Insert the value in the left subtree. else if (this.c.compare(insertMe, here.contents) <= 0) { here.left = this.insert(here.left, insertMe); return here; } // Final case: Greater than the root value. // Insert the value in the right subtree. else { here.right = this.insert(here.right, insertMe); return here; } } // insert(BSTNode, Object) /** * Find a value in the subtree rooted at here. */ public Object find(BSTNode here, Object findMe) throws NotFound { // Case 1: There is no subtree. Fail. if (here == null) throw new NotFound(); // Determine the relationship of the subroot and findMe int rel = this.c.compare(findMe, here.contents); // Case 2: Equal. Return if (rel == 0) return here.contents; // Case 3: Too small. Search left subtree. else if (rel < 0) return find(here.left, findMe); // Case 4: Too large. Search right subtree. else return find(here.right, findMe); } // find(BSTNode, Object) } // class BST