package username.textanalysis; import java.io.PrintWriter; import java.util.Comparator; /** * An implementation of dictionaries using binary search trees. * * @author Samuel A. Rebelsky * @version 2.0 of November 2006 */ public class BST { // +----------------------+------------------------------------ // | Implementation Notes | // +----------------------+ /* (1) A binary search tree is a binary tree in which the left subtree contains keys less than the key stored in the root and the right subtree contains keys greater than the key stored in the root. (2) No duplicate keys are allowed. (3) To support dictionary-type operations, we store both a key and a value in each node. (4) Because putting a value can change the tree, we implement it recursively using a helper method (putInSubtree) that also takes a subtree as a parameter and returns the modified subtree. */ // +--------+-------------------------------------------------- // | Fields | // +--------+ /** * The node that serves as the root of the tree. */ BSTNode root; /** * The comparator used to determine ordering. */ Comparator order; // +--------------+-------------------------------------------- // | Constructors | // +--------------+ /** * Create a new binary search tree with a particular comparator. */ public BST(Comparator _order) { this.root = null; this.order = _order; } // BST() // +--------------------+-------------------------------------- // | Dictionary Methods | // +--------------------+ public void put(K key, V value) { this.root = this.putInSubtree(this.root, key, value); } // put(K,V) public V get(K key) throws Exception { return this.get(this.root, key); } // get(K) public void dump(PrintWriter pen) { this.dump(this.root, pen, ""); } // dump(PrintWriter) public void report(PrintWriter pen) { this.report(this.root, pen); } // report(PrintWriter) // +---------------+------------------------------------------- // | Local Helpers | // +---------------+ /** * Add something to the subtree rooted at n. Return the * new subtree. */ BSTNode putInSubtree(BSTNode top, K key, V value) { // If we've reached the end of the tree, return a new node. if (top == null) { return new BSTNode(key, value); } // Compare the top to the searched value. int relationship = order.compare(key, top.key); // Too small? Look in the left if (relationship < 0) { top.left = this.putInSubtree(top.left, key, value); } // Too large? Look in the right else if (relationship > 0) { top.right = this.putInSubtree(top.right, key, value); } // Otherwise, update the node else { top.value = value; } return top; } // put(BSTNode, K, V) /** * Get the value in the node with key key. */ V get(BSTNode top, K key) throws Exception { // If we've reached the end of the tree, give up. if (top == null) throw new Exception("Invalid key: " + key.toString()); // Compare the current key to the searched value. int relationship = order.compare(key, top.key); // Is the desired key smaller? If so, look in the left. if (relationship < 0) { return get(top.left, key); } // Is the desired key larger? If so, look in the right. else if (relationship > 0) { return get(top.right, key); } // Default: matched else { return top.value; } // else } // get(BSTNode, key) /** * Remove the element with key key. */ public void remove(K key) { // STUB } // remove(K) /** * Dump the tree with a certain indendation */ public void dump(BSTNode top, PrintWriter pen, String indent) { // Sanity check if (top == null) return; // Dump away pen.println(indent + top.key + " => " + top.value); dump(top.left, pen, indent + " L "); dump(top.right, pen, indent + " R "); } // dump(BSTNode, PrintWriter, String) /** * Print the tree in alphabetical order. * NEEDS TO BE IMPLEMENTED. */ public void report(BSTNode top, PrintWriter pen) { // STUB dump(top, pen, ""); } // report(BSTNode, PrintWriter) } // class BST