1 package org.feistymeow.algorithms;
4 //hmmm: move to better folder path.
6 // inspired by http://pages.cs.wisc.edu/~cs367-1/readings/Binary-Search-Trees/
9 * The type of node held in our binary search tree.
15 private TreeNode<K, V> left, right;
17 public TreeNode(K key, V value, TreeNode<K, V> left, TreeNode<K, V> right) {
24 public K getKey() { return key; }
25 public V getValue() { return value; }
28 public TreeNode<K, V> getLeft() { return left; }
29 public TreeNode<K, V> getRight() { return right; }
31 public void setKey(K newK) { key = newK; }
32 public void setLeft(TreeNode<K, V> newL) { left = newL; }
33 public void setRight(TreeNode<K, V> newR) { right = newR; }
35 public void setValue(V newV) { value = newV; }
38 class DuplicateException extends RuntimeException
40 private static final long serialVersionUID = 1L;
41 DuplicateException() {}
45 * A binary search tree implementation.
47 * Insert, Delete and Search are done in O(n log(n)) time.
49 public class BinarySearchTree<K extends Comparable<K>, V>
51 private TreeNode<K, V> root; // ptr to the root of the BinarySearchTree
53 public BinarySearchTree() { root = null; }
56 // add key and associated value to this BinarySearchTree;
57 // error if key is already there
58 public void insert(K key, V value) throws DuplicateException {
59 root = insert(root, value, key);
62 private TreeNode<K, V> insert(TreeNode<K, V> n, V value, K key) throws DuplicateException {
64 return new TreeNode<K, V>(key, value, null, null);
67 if (n.getKey().equals(key)) {
68 throw new DuplicateException();
71 if (key.compareTo(n.getKey()) < 0) {
72 // add key to the left subtree
73 n.setLeft( insert(n.getLeft(), value, key) );
78 // add key to the right subtree
79 n.setRight( insert(n.getRight(), value, key) );
84 // remove the node containing key from this BinarySearchTree if it is there;
85 // otherwise, do nothing
86 public void delete(K key) {
87 root = delete(root, key);
91 private K smallest(TreeNode<K, V> n)
92 // precondition: n is not null
93 // postcondition: return the smallest value in the subtree rooted at n
96 if (n.getLeft() == null) {
99 return smallest(n.getLeft());
103 private TreeNode<K, V> delete(TreeNode<K, V> n, K key)
109 if (key.equals(n.getKey())) {
111 if (n.getLeft() == null && n.getRight() == null) {
114 if (n.getLeft() == null) {
117 if (n.getRight() == null) {
121 // if we get here, then n has 2 children
122 K smallVal = smallest(n.getRight());
124 n.setRight( delete(n.getRight(), smallVal) );
128 else if (key.compareTo(n.getKey()) < 0) {
129 n.setLeft( delete(n.getLeft(), key) );
134 n.setRight( delete(n.getRight(), key) );
140 // if key is in this BinarySearchTree, return its associated value; otherwise, return null
141 public boolean lookup(K key) {
142 return lookup(root, key);
145 private boolean lookup(TreeNode<K, V> n, K key) {
150 if (n.getKey().equals(key)) {
154 if (key.compareTo(n.getKey()) < 0) {
155 // key < this node's key; look in left subtree
156 return lookup(n.getLeft(), key);
160 // key > this node's key; look in right subtree
161 return lookup(n.getRight(), key);
165 // // print the values in this BinarySearchTree in sorted order (to p)
166 // public void print(PrintStream p) {