@Override protected void balance(AVLNode<T> node) { /* Rotation cases (N = node, C = child) * Case 1: * N * / * C * / * O * * Case 2: * N * / * C * \ * O * * Case 3: * N * \ * C * \ * O * Case 4: * N * \ * C * / * O */ if (node == null) return; int bf = node.getBalanceFactor(); if (bf == 2) { AVLNode<T> child = node.getLeftChild(); if (child.getBalanceFactor() == -1) // Case 2 rotateLeft(child); rotateRight(node); // Case 1 } else if (bf == -2) { AVLNode<T> child = node.getRightChild(); if (child.getBalanceFactor() == 1) // Case 4 rotateRight(child); rotateLeft(node); // Case 3 } else balance(node.getParent()); // Recurrsively balance parent }
/** {@inheritDoc} */ @Override protected boolean validateNode(Node<T> node) { boolean bst = super.validateNode(node); if (!bst) return false; AVLNode<T> avlNode = (AVLNode<T>) node; int balanceFactor = avlNode.getBalanceFactor(); if (balanceFactor > 1 || balanceFactor < -1) { return false; } if (avlNode.isLeaf()) { if (avlNode.height != 1) return false; } else { AVLNode<T> avlNodeLesser = (AVLNode<T>) avlNode.lesser; int lesserHeight = 1; if (avlNodeLesser != null) lesserHeight = avlNodeLesser.height; AVLNode<T> avlNodeGreater = (AVLNode<T>) avlNode.greater; int greaterHeight = 1; if (avlNodeGreater != null) greaterHeight = avlNodeGreater.height; if (avlNode.height == (lesserHeight + 1) || avlNode.height == (greaterHeight + 1)) return true; return false; } return true; }
/** * Balance the tree according to the AVL post-insert algorithm. * * @param node Root of tree to balance. */ private void balanceAfterInsert(AVLNode<T> node) { int balanceFactor = node.getBalanceFactor(); if (balanceFactor > 1 || balanceFactor < -1) { AVLNode<T> child = null; Balance balance = null; if (balanceFactor < 0) { child = (AVLNode<T>) node.lesser; balanceFactor = child.getBalanceFactor(); if (balanceFactor < 0) balance = Balance.LEFT_LEFT; else balance = Balance.LEFT_RIGHT; } else { child = (AVLNode<T>) node.greater; balanceFactor = child.getBalanceFactor(); if (balanceFactor < 0) balance = Balance.RIGHT_LEFT; else balance = Balance.RIGHT_RIGHT; } if (balance == Balance.LEFT_RIGHT) { // Left-Right (Left rotation, right rotation) rotateLeft(child); rotateRight(node); } else if (balance == Balance.RIGHT_LEFT) { // Right-Left (Right rotation, left rotation) rotateRight(child); rotateLeft(node); } else if (balance == Balance.LEFT_LEFT) { // Left-Left (Right rotation) rotateRight(node); } else { // Right-Right (Left rotation) rotateLeft(node); } child.updateHeight(); node.updateHeight(); } }
/** * Balance the tree according to the AVL post-delete algorithm. * * @param node Root of tree to balance. */ private void balanceAfterDelete(AVLNode<T> node) { int balanceFactor = node.getBalanceFactor(); if (balanceFactor == -2 || balanceFactor == 2) { if (balanceFactor == -2) { AVLNode<T> ll = (AVLNode<T>) node.lesser.lesser; int lesser = (ll != null) ? ll.height : 0; AVLNode<T> lr = (AVLNode<T>) node.lesser.greater; int greater = (lr != null) ? lr.height : 0; if (lesser >= greater) { rotateRight(node); node.updateHeight(); if (node.parent != null) ((AVLNode<T>) node.parent).updateHeight(); } else { rotateLeft(node.lesser); rotateRight(node); AVLNode<T> p = (AVLNode<T>) node.parent; if (p.lesser != null) ((AVLNode<T>) p.lesser).updateHeight(); if (p.greater != null) ((AVLNode<T>) p.greater).updateHeight(); p.updateHeight(); } } else if (balanceFactor == 2) { AVLNode<T> rr = (AVLNode<T>) node.greater.greater; int greater = (rr != null) ? rr.height : 0; AVLNode<T> rl = (AVLNode<T>) node.greater.lesser; int lesser = (rl != null) ? rl.height : 0; if (greater >= lesser) { rotateLeft(node); node.updateHeight(); if (node.parent != null) ((AVLNode<T>) node.parent).updateHeight(); } else { rotateRight(node.greater); rotateLeft(node); AVLNode<T> p = (AVLNode<T>) node.parent; if (p.lesser != null) ((AVLNode<T>) p.lesser).updateHeight(); if (p.greater != null) ((AVLNode<T>) p.greater).updateHeight(); p.updateHeight(); } } } }