interface Comparator{ int compare(Object obj1, Object obj2); } /* interface ISame{ // determine whether the this objects represent the same information // as the given one boolean same(Object obj); } */ // to represent a traversal of a data type interface Traversal{ // produce the currently first object in the data set Object current(); // advance to the next element of the data set Traversal advance(); // are there more items to produce/advance over? boolean hasMore(); } // Represents a binary search tree abstract public class ABST implements ISame, Traversal { // must establish at the beginning the mode for comparison Comparator c; // inserts an Object into this tree abstract ABST insert(Object obj); // removes an Object from this tree and returns the resulting tree abstract ABST remove(Object obj); // is this tree the same as the given object? abstract public boolean same(Object obj); // produce the currently first object in the data set abstract public Object current(); // advance to the next element of the data set abstract public Traversal advance(); // are there more items to produce/advance over? abstract public boolean hasMore(); } class BSTLeaf extends ABST { BSTLeaf(Comparator c){ this.c = c; } // inserts an Object into this tree ABST insert(Object obj) { return new BSTNode(obj, this, this); } // removes an Object from this tree and returns the resulting tree ABST remove(Object obj) { return this; /* throw new UnsupportedOperationException( "Object cannot be removed from an empty tree"); */ } /*---- methods to compare equality --------------------*/ // is this leaf the same as the given object? public boolean same(Object obj) { return obj instanceof BSTLeaf; } /*---- methods to implement Traversal -----------------*/ // produce the currently first object in the data set public Object current() { return this; /* throw new UnsupportedOperationException( "No current Object in an empty tree"); */ } // advance to the next element of the data set public Traversal advance() { return this; /* throw new UnsupportedOperationException( "Cannot advance in an empty tree"); */ } // are there more items to produce/advance over? public boolean hasMore() { return false; } public String toString() {return "n()";} } // import java.util.Comparator; // represents an internal node in a binary search tree class BSTNode extends ABST { Object data; ABST left; ABST right; BSTNode(Object data, ABST left, ABST right) { this.c = left.c; this.data = data; this.right = right; this.left = left; } // inserts an Object into this tree ABST insert(Object obj) { // // If o is to the left recur down the left // if (c.compare(obj, this.data) < 0) return new BSTNode(this.data, this.left.insert(obj), this.right); // // If o is to the left recur down the left // else if (c.compare(obj, this.data) > 0) return new BSTNode(this.data, this.left, this.right.insert(obj)); // // If we've inserted this data we're done // else return this; } // removes an Object from this tree and returns the resulting tree ABST remove(Object obj) { // // If obj is before current data remove from the left subtree // if (c.compare(obj, this.data) < 0) return new BSTNode(this.data, this.left.remove(obj), this.right); // // If obj is after current data remove from the right subtree // else if (c.compare(obj, this.data) > 0) return new BSTNode(this.data, this.left, this.right.remove(obj)); else return removeRoot(); } // produce a tree with the root removed from this tree ABST removeRoot(){ // no right child -- retur left subtree if (this.right instanceof BSTLeaf) return this.left; // no left child -- return right subtree else if (this.left instanceof BSTLeaf) return this.right; // If both left and right have kids, find the first of the right subtree // and return a new node with that data and the following kids: // - left: untouched left // - right: new node constructed of the left without the first value // else return new BSTNode(((BSTNode)this.right).findFirst(), this.left, ((BSTNode)this.right).removeFirst()); } // find the first item in this binary search tree Object findFirst() { if (this.left instanceof BSTLeaf) return this.data; else return ((BSTNode)this.left).findFirst(); } // produce the tree with the first node removed from this tree ABST removeFirst(){ if (this.left instanceof BSTLeaf) return this.right; else return new BSTNode(this.data, ((BSTNode)this.left).removeFirst(), this.right); } /*---- methods to compare equality --------------------*/ // is this BSTNode the same as the given object? public boolean same(Object a) { if (!(a instanceof BSTNode)) return false; else return this.sameBSTNode((BSTNode) a); } // is this BSTNode the same as the given BSTNode? boolean sameBSTNode(BSTNode that){ return this.data.equals(that.data) && this.left.same(that.left) && this.right.same(that.right); } /*---- methods to implement Traversal -----------------*/ // produce the currently first object in the data set public Object current() { return findFirst(); } // advance to the next element of the data set public Traversal advance() { return this.removeFirst(); } // are there more items to produce/advance over? public boolean hasMore() { return true; } /*---- method to allow pretty printing ----------------*/ public String toString() { return "n(".concat(this.data.toString()).concat(", ").concat( this.left.toString()).concat(", ").concat( this.right.toString()).concat(")"); } } interface ILoObject extends ISame{} class MTLoObject implements ILoObject{ MTLoObject() {} int size(){ return 0; } boolean contains (Object that){ return false; } // is this the same as the given object? public boolean same(Object obj){ return obj instanceof MTLoObject; } } class ConsLoObject implements ILoObject{ Object first; ILoObject rest; ConsLoObject(Object first, ILoObject rest){ this.first = first; this.rest = rest; } /* TEMPLATE: ... this.first ... -- Object ... this.rest ... -- ILoObject ... this.rest.mm() ... -- nnn */ // is this the same as the given object? public boolean same(Object obj){ if (obj instanceof ConsLoObject) return this.sameConsLoObject(((ConsLoObject)obj)); else return false; } // is this the same as the given ConsLoObject? boolean sameConsLoObject(ConsLoObject that){ return //((ISame)this.first).same(that.first) && this.first.equals(that.first) && this.rest.same(that.rest); } } class StringComparator implements Comparator{ StringComparator(){} public int compare(Object obj1, Object obj2){ return ((String)obj1).compareTo((String)obj2); } } class Examples { Examples () {} // data definitions ABST leaf = new BSTLeaf(new StringComparator()); ABST tree = new BSTNode("b", new BSTNode("a", leaf, leaf), new BSTNode("c", leaf, leaf)); /*------------- algorithms that consume traversals -----------*/ // count the elements in the data set given by the traversal int count(Traversal tr){ if (tr.hasMore()) return 1 + count(tr.advance()); else return 0; } // find the given string in the data set given by the traversal boolean find(Traversal tr, String s){ if (tr.hasMore()) if (((String)tr.current()).equals(s)) return true; else return find(tr.advance(),s); else return false; } // produce a list of objects by removing the given string // from the data set given by the traversal ILoObject remove(Traversal tr, String s){ if (tr.hasMore()) if (((String)tr.current()).equals(s)) return remove(tr.advance(), s); else return new ConsLoObject(tr.current(), remove(tr.advance(),s)); else return new MTLoObject(); } // test methods for count in Examples class boolean testCountABST1 = count(leaf) == 0; boolean testCountABST2 = count(tree) == 3; // test methods for find in Examples class boolean testFindABST1 = find(leaf, "a") == false; boolean testFindABST2 = find(tree, "a") == true; boolean testFindABST3 = find(tree, "d") == false; // test methods for remove in Examples class boolean testRemoveABST1 = remove(tree, "a").same(new ConsLoObject("b", new ConsLoObject("c", new MTLoObject()))); boolean testRemoveABST2 = remove(tree, "b").same(new ConsLoObject("a", new ConsLoObject("c", new MTLoObject()))); boolean testRemoveABST3 = remove(leaf, "a").same(new MTLoObject()); public static void main(String argv[]){ Examples e = new Examples(); System.out.println("testCountABST1: " + e.testCountABST1); System.out.println("testCountABST2: " + e.testCountABST2); System.out.println("testFindABST1: " + e.testFindABST1); System.out.println("testFindABST2: " + e.testFindABST1); System.out.println("testFindABST3: " + e.testFindABST1); System.out.println("testRemoveABST1: " + e.testRemoveABST1); System.out.println("testRemoveABST2: " + e.testRemoveABST2); System.out.println("testRemoveABST3: " + e.testRemoveABST3); } }