class AVLNode<T extends Comparable<T>> { T data; AVLNode<T> left, right; int height; public AVLNode(T data) { this.data = data; this.height = 1; // New node initially has height 1 } } public class AVLTree<T extends Comparable<T>> { private AVLNode<T> root; public AVLTree() { this.root = null; } // Get height of node private int height(AVLNode<T> node) { return node == null ? 0 : node.height; } // Right rotation private AVLNode<T> rotateRight(AVLNode<T> y) { AVLNode<T> x = y.left; AVLNode<T> T2 = x.right; x.right = y; y.left = T2; y.height = Math.max(height(y.left), height(y.right)) + 1; x.height = Math.max(height(x.left), height(x.right)) + 1; return x; } // Left rotation private AVLNode<T> rotateLeft(AVLNode<T> x) { AVLNode<T> y = x.right; AVLNode<T> T2 = y.left; y.left = x; x.right = T2; x.height = Math.max(height(x.left), height(x.right)) + 1; y.height = Math.max(height(y.left), height(y.right)) + 1; return y; } // Balance factor of a node private int getBalance(AVLNode<T> node) { return node == null ? 0 : height(node.left) - height(node.right); } // Insert operation public void insert(T data) { root = insertRec(root, data); } private AVLNode<T> insertRec(AVLNode<T> node, T data) { if (node == null) { return new AVLNode<>(data); } if (data.compareTo(node.data) < 0) { node.left = insertRec(node.left, data); } else if (data.compareTo(node.data) > 0) { node.right = insertRec(node.right, data); } else { return node; } node.height = Math.max(height(node.left), height(node.right)) + 1; int balance = getBalance(node); if (balance > 1 && data.compareTo(node.left.data) < 0) { return rotateRight(node); } if (balance < -1 && data.compareTo(node.right.data) > 0) { return rotateLeft(node); } if (balance > 1 && data.compareTo(node.left.data) > 0) { node.left = rotateLeft(node.left); return rotateRight(node); } if (balance < -1 && data.compareTo(node.right.data) < 0) { node.right = rotateRight(node.right); return rotateLeft(node); } return node; } // Search operation public boolean search(T data) { return searchRec(root, data) != null; } private AVLNode<T> searchRec(AVLNode<T> node, T data) { if (node == null || node.data.equals(data)) { return node; } if (data.compareTo(node.data) < 0) { return searchRec(node.left, data); } else { return searchRec(node.right, data); } } // In-order traversal public void inOrder() { inOrderRec(root); } private void inOrderRec(AVLNode<T> node) { if (node != null) { inOrderRec(node.left); System.out.print(node.data + " "); inOrderRec(node.right); } } // Delete operation public void delete(T data) { root = deleteRec(root, data); } private AVLNode<T> deleteRec(AVLNode<T> root, T data) { if (root == null) { return root; } if (data.compareTo(root.data) < 0) { root.left = deleteRec(root.left, data); } else if (data.compareTo(root.data) > 0) { root.right = deleteRec(root.right, data); } else { if ((root.left == null) || (root.right == null)) { AVLNode<T> temp = root.left != null ? root.left : root.right; if (temp == null) { return null; } else { return temp; } } else { AVLNode<T> temp = minValueNode(root.right); root.data = temp.data; root.right = deleteRec(root.right, temp.data); } } root.height = Math.max(height(root.left), height(root.right)) + 1; int balance = getBalance(root); if (balance > 1 && getBalance(root.left) >= 0) { return rotateRight(root); } if (balance > 1 && getBalance(root.left) < 0) { root.left = rotateLeft(root.left); return rotateRight(root); } if (balance < -1 && getBalance(root.right) <= 0) { return rotateLeft(root); } if (balance < -1 && getBalance(root.right) > 0) { root.right = rotateRight(root.right); return rotateLeft(root); } return root; } private AVLNode<T> minValueNode(AVLNode<T> node) { AVLNode<T> current = node; while (current.left != null) { current = current.left; } return current; } public static void main(String[] args) { AVLTree<Integer> avlTree = new AVLTree<>(); avlTree.insert(10); avlTree.insert(20); avlTree.insert(5); avlTree.insert(6); avlTree.insert(15); avlTree.insert(25); System.out.println("In-order traversal:"); avlTree.inOrder(); System.out.println(); System.out.println("Search 15: " + avlTree.search(15)); System.out.println("Search 100: " + avlTree.search(100)); avlTree.delete(20); System.out.println("In-order traversal after deleting 20:"); avlTree.inOrder(); System.out.println(); } }
Preview:
downloadDownload PNG
downloadDownload JPEG
downloadDownload SVG
Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!
Click to optimize width for Twitter