/** * AVL Trees. Like Binary search trees except they rebalance. */ public class AVL,V> extends BST { // +---------+----------------------------------------------------- // | Methods | // +---------+ BSTNode insert(BSTNode node, K key, V value) { node = super.insert(node, key, value); return rebalance(node); } // insert BSTNode remove(BSTNode node, K key) { node = super.remove(node, key); return node; } // remove(BSTNode, K) Pair,BSTNode> removeLargest(BSTNode node) { Pair,BSTNode> tmp = super.removeLargest(node); return tmp; } // removeLargest(BSTNode) BSTNode rebalance(BSTNode node) { // If the left subtree is too tall if (BSTNode.height(node.left()) - BSTNode.height(node.right()) > 1) { BSTNode left = node.left(); // The easy case if (BSTNode.height(left.left()) > BSTNode.height(left.right())) { return rotateRight(node); } // The hard case else { node.setLeft(rotateLeft(node.left())); return rotateRight(node); } } // If the right subtree is too tall else if (BSTNode.height(node.right()) - BSTNode.height(node.left()) > 1) { BSTNode right = node.right(); // The easy case if (BSTNode.height(right.right()) > BSTNode.height(right.left())) { return rotateLeft(node); } // The hard case else { node.setRight(rotateRight(node.right())); return rotateLeft(node); } } // No rebalance needed else { return node; } } // rebalance /** * node left * / \ / \ * left t3 => t1 node * / \ / \ * t1 t2 t2 t3 */ BSTNode rotateRight(BSTNode node) { BSTNode left = node.left(); node.setLeft(left.right()); left.setRight(node); return left; } // rotateRight(BSTNode) /** * node right * / \ / \ * t1 right => node t3 * / \ / \ * t2 t3 t1 t2 */ BSTNode rotateLeft(BSTNode node) { BSTNode right = node.right(); node.setRight(right.left()); right.setLeft(node); return right; } // rotateLeft(BSTNode) } // class AVL