public static void rotateRight(AVLNode origRoot) { // === Difference from rotateLeft === AVLNode newRoot = origRoot.left; // Original root's left (previously new root) becomes new root's right origRoot.left = newRoot.right; // New root's right becomes original root newRoot.right = origRoot; // If original root is not root of tree if (origRoot.parent != null) { // Update new root's parent's link to it based on // whether original root is left or right child if (origRoot.parent.left.key == origRoot.key) { origRoot.parent.left = newRoot; } else { origRoot.parent.right = newRoot; } } // Update new root's parent to be original root's parent newRoot.parent = origRoot.parent; // Update original root's parent to be new root origRoot.parent = newRoot; // Update heights of original and new root newRoot.height -= 1; origRoot.height += 1; }
static AVLNode rebalancing(AVLNode root) { root.ht = Math.max(height(root.left), height(root.right)) + 1; int bf = height(root.left) - height(root.right); if (bf > 1) { bf = height(root.left.left) - height(root.left.right); if (bf < 0) { root.left = rotate(root.left, true); } root = rotate(root, false); } else if (bf < -1) { bf = height(root.right.left) - height(root.right.right); if (bf > 0) { root.right = rotate(root.right, false); } root = rotate(root, true); } return root; }
protected AVLNode<T> insert(T data, AVLNode<T> t) throws Exception { if (t == null) t = new AVLNode<T>(data); else if (data.compareTo(t.data) < 0) { t.left = insert(data, t.left); if (height(t.left) - height(t.right) == 2) { if (data.compareTo(t.left.data) < 0) { t = rotateWithLeftChild(t); countSingleRotations++; } else { t = doubleRotateWithleftChild(t); countDoubleRotations++; } } } else if (data.compareTo(t.data) > 0) { t.right = insert(data, t.right); if (height(t.right) - height(t.left) == 2) { if (data.compareTo(t.right.data) > 0) { t = rotateWithRightChild(t); countSingleRotations++; } else { t = doubleRotateWithRightChild(t); countDoubleRotations++; } } } else { throw new Exception("Attempting to insert to duplicate value"); } t.height = max(height(t.left), height(t.right)) + 1; return t; }
static AVLNode rotate(AVLNode root, boolean isLeft) { if (isLeft) { AVLNode right = root.right; root.right = right.left; right.left = root; root.ht = Math.max(height(root.left), height(root.right)) + 1; root = right; root.ht = Math.max(height(root.left), height(root.right)) + 1; } else { AVLNode left = root.left; root.left = left.right; left.right = root; root.ht = Math.max(height(root.left), height(root.right)) + 1; root = left; root.ht = Math.max(height(root.left), height(root.right)) + 1; } return root; }
protected AVLNode<T> rotateWithRightChild(AVLNode<T> root) { AVLNode<T> newRoot = root.right; root.right = newRoot.left; newRoot.left = root; root.height = max(height(root.left), height(root.right)) + 1; newRoot.height = max(height(newRoot.right), root.height) + 1; return newRoot; }
public AVLNode<T> remove(T x, AVLNode<T> t) { if (t == null) { System.out.println("Sorry but you're mistaken, " + t + " doesn't exist in this tree :)\n"); return null; } System.out.println("Remove starts... " + t.data + " and " + x); if (x.compareTo(t.data) < 0) { t.left = remove(x, t.left); int le = t.left != null ? t.left.height : 0; if ((t.right != null) && (t.right.height - le >= 2)) { int rightHeight = t.right.right != null ? t.right.right.height : 0; int leftHeight = t.right.left != null ? t.right.left.height : 0; if (rightHeight >= leftHeight) t = rotateWithLeftChild(t); else t = doubleRotateWithRightChild(t); } } else if (x.compareTo(t.data) > 0) { t.right = remove(x, t.right); int ri = t.right != null ? t.right.height : 0; if ((t.left != null) && (t.left.height - ri >= 2)) { int leftHeight = t.left.left != null ? t.left.left.height : 0; int rightHeight = t.left.right != null ? t.left.right.height : 0; if (leftHeight >= rightHeight) t = rotateWithRightChild(t); else t = doubleRotateWithleftChild(t); } } else if (t.left != null) { t.data = findMax(t.left).data; remove(t.data, t.left); if ((t.right != null) && (t.right.height - t.left.height >= 2)) { int rightHeight = t.right.right != null ? t.right.right.height : 0; int leftHeight = t.right.left != null ? t.right.left.height : 0; if (rightHeight >= leftHeight) t = rotateWithLeftChild(t); else t = doubleRotateWithRightChild(t); } } else { t = (t.left != null) ? t.left : t.right; } if (t != null) { int leftHeight = (t.left != null) ? t.left.height : 0; int rightHeight = (t.right != null) ? t.right.height : 0; t.height = max(leftHeight, rightHeight) + 1; } return t; }
// https://www.hackerrank.com/challenges/self-balancing-tree public AVLNode insert(AVLNode root, int val) { if (root == null) { AVLNode node = new AVLNode(); node.val = val; node.ht = 0; return node; } if (root.val > val) { root.left = insert(root.left, val); } else { root.right = insert(root.right, val); } return rebalancing(root); }
protected AVLNode<T> doubleRotateWithleftChild(AVLNode<T> root) { root.left = rotateWithRightChild(root.left); return rotateWithLeftChild(root); }