class AVLNode { int key; int height; AVLNode left; AVLNode right; public AVLNode(int key) { this.key = key; this.height = 1; } } public class AVLTree { private AVLNode root; public AVLTree() { root = null; } // Insert a key into the AVL tree public void insert(int key) { root = insertRec(root, key); } // Helper method to recursively insert a key into the AVL tree private AVLNode insertRec(AVLNode node, int key) { if (node == null) return new AVLNode(key); if (key < node.key) node.left = insertRec(node.left, key); else if (key > node.key) node.right = insertRec(node.right, key); else // Duplicate keys are not allowed return node; // Update height of this node node.height = 1 + Math.max(height(node.left), height(node.right)); // Get balance factor and perform rotations if needed int balance = getBalance(node); // Left Left Case if (balance > 1 && key < node.left.key) return rightRotate(node); // Right Right Case if (balance < -1 && key > node.right.key) return leftRotate(node); // Left Right Case if (balance > 1 && key > node.left.key) { node.left = leftRotate(node.left); return rightRotate(node); } // Right Left Case if (balance < -1 && key < node.right.key) { node.right = rightRotate(node.right); return leftRotate(node); } return node; } // Perform right rotation private AVLNode rightRotate(AVLNode y) { AVLNode x = y.left; AVLNode T2 = x.right; // Perform rotation x.right = y; y.left = T2; // Update heights y.height = Math.max(height(y.left), height(y.right)) + 1; x.height = Math.max(height(x.left), height(x.right)) + 1; return x; } // Perform left rotation private AVLNode leftRotate(AVLNode x) { AVLNode y = x.right; AVLNode T2 = y.left; // Perform rotation y.left = x; x.right = T2; // Update heights x.height = Math.max(height(x.left), height(x.right)) + 1; y.height = Math.max(height(y.left), height(y.right)) + 1; return y; } // Get height of a node private int height(AVLNode node) { if (node == null) return 0; return node.height; } // Get balance factor of a node private int getBalance(AVLNode node) { if (node == null) return 0; return height(node.left) - height(node.right); } // Find the inorder successor private AVLNode minValueNode(AVLNode node) { AVLNode current = node; while (current.left != null) current = current.left; return current; } // Delete a key from the AVL tree public void delete(int key) { root = deleteRec(root, key); } // Helper method to recursively delete a key from the AVL tree private AVLNode deleteRec(AVLNode root, int key) { if (root == null) return root; if (key < root.key) root.left = deleteRec(root.left, key); else if (key > root.key) root.right = deleteRec(root.right, key); else { // Node to be deleted found // Case 1: Node with one child or no child if (root.left == null || root.right == null) { AVLNode temp = null; if (root.left != null) temp = root.left; else temp = root.right; // No child case if (temp == null) { temp = root; root = null; } else // One child case root = temp; // Copy the contents of the non-empty child temp = null; } else { // Case 2: Node with two children AVLNode temp = minValueNode(root.right); root.key = temp.key; root.right = deleteRec(root.right, temp.key); } } // If the tree had only one node then return if (root == null) return root; // Update height of the current node root.height = 1 + Math.max(height(root.left), height(root.right)); // Get balance factor and perform rotations if needed int balance = getBalance(root); // Left Left Case if (balance > 1 && getBalance(root.left) >= 0) return rightRotate(root); // Left Right Case if (balance > 1 && getBalance(root.left) < 0) { root.left = leftRotate(root.left); return rightRotate(root); } // Right Right Case if (balance < -1 && getBalance(root.right) <= 0) return leftRotate(root); // Right Left Case if (balance < -1 && getBalance(root.right) > 0) { root.right = rightRotate(root.right); return leftRotate(root); } return root; } // Inorder traversal of the AVL tree public void inorder() { inorderRec(root); System.out.println(); } // Helper method to recursively perform inorder traversal of the AVL tree private void inorderRec(AVLNode root) { if (root != null) { inorderRec(root.left); System.out.print(root.key + " "); inorderRec(root.right); } } public static void main(String[] args) { AVLTree tree = new AVLTree(); // Insert elements into the AVL tree tree.insert(9); tree.insert(5); tree.insert(10); tree.insert(0); tree.insert(6); tree.insert(11); tree.insert(-1); tree.insert(1); tree.insert(2); // Inorder traversal of the AVL tree System.out.println("Inorder traversal of AVL tree:"); tree.inorder(); // Delete an element from the AVL tree int keyToDelete = 10; System.out.println("Deleting key " + keyToDelete + " from AVL tree"); tree.delete(keyToDelete); // Inorder traversal after deletion System.out.println("Inorder traversal after deletion:"); tree.inorder(); } }