/** * Tree implementation of the Set ADT */ public class StringTreeSet implements StringSet { private StringTreeNode root; private int numElements; /** * Adds the specified String to the Set if it is not already present. * @return true if this set did not already contain the String */ public boolean add(String value) { int oldSize = size(); root = add(root, value); return oldSize != size(); } private StringTreeNode add(StringTreeNode node, String value) { if (node == null) { node = new StringTreeNode(value); numElements++; } else if (value.compareTo(node.data) == 0) { // do nothing! } else if (value.compareTo(node.data) < 0) { node.left = add(node.left, value); } else { // value ">" node.data node.right = add(node.right, value); } return node; } /** * Returns true if the set contains the specified String. */ public boolean contains(String value) { return contains(root, value); } private boolean contains(StringTreeNode node, String value) { if (node == null) { return false; } else if (value.compareTo(node.data) == 0) { return true; } else if (value.compareTo(node.data) < 0) { return contains(node.left, value); } else { // value ">" node.data return contains(node.right, value); } } /** * Prints the set in a tree-like format. */ public void print() { print(root, 0); } /** * Recursive print helper; in-order traversal. * @param node * @param level */ private void print(StringTreeNode node, int level) { if (node != null) { print(node.right, level + 1); printTabs(level); System.out.println(node.data); print(node.left, level + 1); } } private void printTabs(int level) { for (int i = 0; i < level; i++) { System.out.print("\t"); } } /** * Removes the specified String from this set if it is present. * @return true if this set contained the specified element */ public boolean remove(String value) { int oldSize = size(); root = remove(root, value); return oldSize > size(); } private StringTreeNode remove(StringTreeNode node, String value) { if (node == null) { // do nothing! } else if (value.compareTo(node.data) < 0) { node.left = remove(node.left, value); } else if (value.compareTo(value) > 0) { node.right = remove(node.right, value); } else { if (node.right != null && node.left != null) { node.data = getMinValue(node.right); node.right = remove(node.right, node.data); } else if (node.right != null) { node = node.right; numElements--; } else { node = node.left; numElements--; } } return node; } // gets the minimum value in the tree rooted at the given node private String getMinValue(StringTreeNode node) { if (node.left == null) { return node.data; } else { return getMinValue(node.left); } } /** * Returns the number of elements in this set (its cardinality) */ public int size() { return numElements; } /** * Returns a String representation of StringTreeSet with elements in * their "natural order" (e.g., [Jake, Kasey, Marisa, Robert]). This is * an example of an in-order traversal. */ public String toString() { String retVal = "[" + toString(root); if (retVal.length() > 1) { retVal = retVal.substring(0, retVal.length()-2); // remove extra comma and space } return retVal + "]"; } private String toString(StringTreeNode node) { String retVal = ""; if (node != null) { retVal += toString(node.left); retVal += node.data; retVal += ", "; retVal += toString(node.right); } return retVal; } }