import java.util.Formatter; /** A node of a binary search tree associating a value of type VALUE * with a key of type KEY. (Thus, the labels in this tree are * key/value pairs.) * @author P. N. Hilfinger */ class BST, Value> { Key key; Value value; BST left, right; /** A new BST node mapping KEY -> VALUE, with subtrees LEFT and RIGHT. */ BST(Key key0, Value value0, BST left0, BST right0) { key = key0; value = value0; this.left = left0; this.right = right0; } /** A new BST leaf node mapping KEY -> VALUE. */ BST(Key key0, Value value0) { this(key0, value0, null, null); } /** Return the node in T containing L, or null if none. */ static , Value> BST find(BST T, Key L) { if (T == null) { return T; } else if (L.compareTo(T.key) == 0) { return T; } else if (L.compareTo(T.key) < 0) return find(T.left, L); else { return find(T.right, L); } } /** Insert V in T with key K, replacing existing * value if present, and return the modified tree. */ static , Value> BST insert(BST T, Key K, Value V) { if (T == null) return new BST<>(K, V); if (K.compareTo(T.key) == 0) T.value = V; else if (K.compareTo(T.key) < 0) T.left = insert(T.left, K, V); else T.right = insert(T.right, K, V); return T; } /** Remove K from T, and return the new tree. */ static , Value> BST remove(BST T, Key K) { if (T == null) return null; if (K.compareTo(T.key) == 0) { if (T.left == null) return T.right; else if (T.right == null) return T.left; else { BST smallest = minNode(T.right); // ?? T.value = smallest.value; T.key = smallest.key; T.right = remove(T.right, smallest.key); } } else if (K.compareTo(T.key) < 0) T.left = remove(T.left, K); else T.right = remove(T.right, K); return T; } /** Return the node containing the minimal key T. T must not be null. */ public static , Value> BST minNode(BST T) { while (T.left != null) { T = T.left; } return T; } private , Value> void pTree(BST T, int indent, Formatter out) { for (int i = 0; i < indent; i += 1) { out.format(" "); } if (T == null) { out.format("()"); return; } out.format("(%s [%s]", T.key, T.value); if (T.left != null || T.right != null) { out.format("%n"); pTree(T.left, indent + 4, out); out.format("%n"); pTree(T.right, indent + 4, out); } out.format(")"); } @Override public String toString() { Formatter out = new Formatter(); pTree(this, 0, out); return out.toString(); } }