/** * Add <tt>element</tt> to the tree. * * @param parent parent of <tt>node</tt> * @param node root of subtree to which element is to be added * @param element the element to be added to the tree * @throws SearchTreeException if node is found in the tree */ protected BSTNode<E> add(BSTNode<E> parent, BSTNode<E> node, E element) { if (node == null) { // base case node = new AVLNode(element); node.parent = parent; } else { // recursive case int compareResult = element.compareTo(node.getElement()); if (compareResult < 0) { node.leftChild = add(node, node.leftChild, element); } else if (compareResult > 0) { node.rightChild = add(node, node.rightChild, element); } else { throw new SearchTreeException("Duplicate element: " + element.toString()); } // now do height/balance updates and possible // subtree fixes node = fixSubtreeRootedAt((AVLNode<E>) node); } return node; }
/** * Remove element from this tree. * * @param nodethe root of the subtree from which to remove element. * @param element the element to remove. */ protected BSTNode<E> remove(BSTNode<E> node, E target) { if (node == null) { // element isn't in the tree return null; } int compareResult = target.compareTo(node.getElement()); if (compareResult < 0) { node.leftChild = remove(node.leftChild, target); node = fixSubtreeRootedAt((AVLNode<E>) node); } else if (compareResult > 0) { node.rightChild = remove(node.rightChild, target); node = fixSubtreeRootedAt((AVLNode<E>) node); } else { // found the target! this.size--; // handle the case of two children first if ((node.leftChild != null) && (node.rightChild != null)) { BSTNode<E> replacement = successor(node); node.setElement(replacement.getElement()); // now deal with removing the replacement BSTNode<E> newChild = replacement.leftChild == null ? replacement.rightChild : replacement.leftChild; if (replacement == replacement.parent.leftChild) { replacement.parent.leftChild = newChild; } else { replacement.parent.rightChild = newChild; } // now fix the height/balance from the replacement's // parent to node // if, along the way, we find a subtree unbalanced, // rebalance it node = updatePath((AVLNode<E>) node, replacement.parent.getElement()); } else { // Collapse the cases of no children and 1 child node = (node.leftChild == null) ? node.rightChild : node.leftChild; } } return node; }