/** * Removes the largest key and associated value from the symbol table. * * @throws NoSuchElementException if the symbol table is empty */ public void deleteMax() { if (isEmpty()) throw new NoSuchElementException("BST underflow"); // if both children of root are black, set root to red if (!isRed(root.left) && !isRed(root.right)) root.color = RED; root = deleteMax(root); if (!isEmpty()) root.color = BLACK; // assert check(); }
/** * Removes the key and associated value from the symbol table (if the key is in the symbol table). * * @param key the key * @throws NullPointerException if <tt>key</tt> is <tt>null</tt> */ public void delete(Key key) { if (!contains(key)) { System.err.println("symbol table does not contain " + key); return; } // if both children of root are black, set root to red if (!isRed(root.left) && !isRed(root.right)) root.color = RED; root = delete(root, key); if (!isEmpty()) root.color = BLACK; // assert check(); }
public void add(int key) { if (elemCount == 0) { root = new Node(key, Color.BLACK); root.left = new Node(-1, null, null, root, Color.BLACK); numOfLeaves++; root.right = new Node(-1, null, null, root, Color.BLACK); numOfLeaves++; } else if (lookup(key)) { System.out.println("Cannot accept duplicate values"); } else { do { if (key <= root.key) { root = root.left; } else { root = root.right; } } while (root.key != -1); root.key = key; root.color = Color.RED; root.left = new Node(-1, null, null, root, Color.BLACK); root.right = new Node(-1, null, null, root, Color.BLACK); numOfLeaves++; fixTree(root); } elemCount++; resetRoot(); }
// flip the colors of a node and its two children private void flipColors(Node h) { // h must have opposite color of its two children // assert (h != null) && (h.left != null) && (h.right != null); // assert (!isRed(h) && isRed(h.left) && isRed(h.right)) // || (isRed(h) && !isRed(h.left) && !isRed(h.right)); h.color = !h.color; h.left.color = !h.left.color; h.right.color = !h.right.color; }
// make a right-leaning link lean to the left private Node rotateLeft(Node h) { // assert (h != null) && isRed(h.right); Node x = h.right; h.right = x.left; x.left = h; x.color = x.left.color; x.left.color = RED; x.N = h.N; h.N = size(h.left) + size(h.right) + 1; return x; }
private void fixTree(Node node) { if (node.parent == null) { // if we reached the root node.color = Color.BLACK; } else if (node.parent.color == Color.BLACK) { } else { Node uncle = uncle(node); // Case 1: Parent is red and Uncle is red if (node.parent.color == Color.RED && uncle.color == Color.RED) { node.parent.parent.left.color = Color.BLACK; node.parent.parent.right.color = Color.BLACK; node.parent.parent.color = Color.RED; fixTree(node.parent.parent); } // Case 2: Parent is red and Uncle is black else { // Uncle is left & node is right if (!isRightChild(uncle) && isRightChild(node)) { leftRotate(node.parent.parent); node.parent.color = Color.BLACK; node.parent.left.color = Color.RED; } // Uncle is left & node is left else if (!isRightChild(uncle) && !isRightChild(node)) { rightRotate(node.parent); fixTree(node.parent); } // Uncle is right & node is right else if (isRightChild(uncle) && isRightChild(node)) { leftRotate(node.parent); fixTree(node.parent); } // Uncle is right & node is left else if (isRightChild(uncle) && !isRightChild(node)) { rightRotate(node.parent.parent); node.parent.color = Color.BLACK; node.parent.right.color = Color.RED; } } } }
/** * Inserts the key-value pair into the symbol table, overwriting the old value with the new value * if the key is already in the symbol table. If the value is <tt>null</tt>, this effectively * deletes the key from the symbol table. * * @param key the key * @param val the value * @throws NullPointerException if <tt>key</tt> is <tt>null</tt> */ public void put(Key key, Value val) { root = put(root, key, val); root.color = BLACK; // assert check(); }