// CSE 143, Winter 2009, Marty Stepp // An implementation of a set using a binary search tree as the // underlying data structure. // // This version uses generics to be able to store any type of element. // It also implements the common AnythingSet interface like HashAnythingSet. // It also has its TreeNode as an inner class. import java.util.NoSuchElementException; public class TreeAnythingSet> implements AnythingSet { private TreeNode overallRoot; // Constructs a new empty binary search tree. public TreeAnythingSet() { overallRoot = null; } // Adds the given value to this binary search tree. // If the value is already contained in the tree, no change is made. public void add(E value) { overallRoot = add(overallRoot, value); } // Private helper to add the given value to this subtree. private TreeNode add(TreeNode root, E value) { if (root == null) { root = new TreeNode(value); // root -> [49] } else if (root.data.compareTo(value) > 0) { // root.data > value ? root.left = add(root.left, value); } else if (root.data.compareTo(value) < 0) { // root.data < value ? root.right = add(root.right, value); } return root; } // Returns true if this BST contains the given value. public boolean contains(E value) { return contains(overallRoot, value); } // Recursive helper to search the given subtree for the given value. private boolean contains(TreeNode root, E value) { if (root == null) { return false; } else if (root.data.compareTo(value) == 0) { return true; // this node is the value we're looking for } else if (root.data.compareTo(value) > 0) { return contains(root.left, value); // this node is too large; go left } else { // root.data < value return contains(root.right, value); // this node is too small; go right } } // Removes the given value from this BST, if it exists. // If the value is not contained in the tree, no change is made. public void remove(E value) { overallRoot = remove(overallRoot, value); } // Recursive helper to find the subtree with the given value and remove it private TreeNode remove(TreeNode root, E value) { if (root == null) { return null; } else if (root.data.compareTo(value) > 0) { root.left = remove(root.left, value); // too big; go left } else if (root.data.compareTo(value) < 0) { root.right = remove(root.right, value); // too small; go right } else { // root.data == value; remove this node if (root.right == null) { return root.left; // no R child; replace w/ L } else if (root.left == null) { return root.right; // no L child; replace w/ R } else { // both children; replace w/ min from R root.data = getMin(root.right); root.right = remove(root.right, root.data); } } return root; } // Returns the minimum value from this BST. // Throws a NoSuchElementException if the tree is empty. public E getMin() { if (overallRoot == null) { throw new NoSuchElementException(); } return getMin(overallRoot); } // Recursive helper to search a subtree and return the minimum (leftmost) value. private E getMin(TreeNode root) { if (root.left == null) { return root.data; } else { return getMin(root.left); } } // Prints the tree in a sideways indented format. // Elements are printed one per line, indented by 4 spaces. public void printSideways() { printSideways(overallRoot, 0); } // Recursive helper for printing the given subtree sideways at the // given level of indentation. private void printSideways(TreeNode root, int level) { if (root != null) { printSideways(root.right, level + 1); for (int i = 1; i <= level * 4; i++) { System.out.print(" "); } System.out.println(root.data); printSideways(root.left, level + 1); } } // IntTreeNode is a class for storing a single node of a binary tree of ints. private class TreeNode { public E data; // data stored at this node public TreeNode left; // reference to left subtree public TreeNode right; // reference to right subtree // Constructs a leaf node with the given data. public TreeNode(E data) { this(data, null, null); } // Constructs a leaf or branch node with the given data and links. public TreeNode(E data, TreeNode left, TreeNode right) { this.data = data; this.left = left; this.right = right; } } }