diff --git a/src/test/java/com/thealgorithms/tree/AVLtree/AVLDelete.java b/src/test/java/com/thealgorithms/tree/AVLtree/AVLDelete.java new file mode 100644 index 000000000000..59ab8a38ffa5 --- /dev/null +++ b/src/test/java/com/thealgorithms/tree/AVLtree/AVLDelete.java @@ -0,0 +1,125 @@ +package com.thealgorithms.tree.AVLtree; + +public class AVLDelete { + + static class Node { + int key, height; + Node left, right; + + Node(int d) { + key = d; + height = 1; + } + } + + private Node root; + + private int height(Node n) { + return (n == null) ? 0 : n.height; + } + + private int getBalance(Node n) { + return (n == null) ? 0 : height(n.left) - height(n.right); + } + + private Node rightRotate(Node y) { + Node x = y.left; + Node 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; + } + + private Node leftRotate(Node x) { + Node y = x.right; + Node 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; + } + + private Node minValueNode(Node node) { + Node current = node; + while (current.left != null) { + current = current.left; + } + return current; + } + + public Node deleteNode(Node root, int key) { + if (root == null) { + return root; + } + + if (key < root.key) { + root.left = deleteNode(root.left, key); + } else if (key > root.key) { + root.right = deleteNode(root.right, key); + } else { + // Node with only one child or no child + if ((root.left == null) || (root.right == null)) { + Node temp = (root.left != null) ? root.left : root.right; + if (temp == null) { + temp = root; + root = null; + } else { + root = temp; + } + } else { + Node temp = minValueNode(root.right); + root.key = temp.key; + root.right = deleteNode(root.right, temp.key); + } + } + + if (root == null) { + return root; + } + + root.height = Math.max(height(root.left), height(root.right)) + 1; + + 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; + } + + public Node getRoot() { + return root; + } + + public void setRoot(Node root) { + this.root = root; + } +} diff --git a/src/test/java/com/thealgorithms/tree/AVLtree/AVLInsert.java b/src/test/java/com/thealgorithms/tree/AVLtree/AVLInsert.java new file mode 100644 index 000000000000..47da2a09acd6 --- /dev/null +++ b/src/test/java/com/thealgorithms/tree/AVLtree/AVLInsert.java @@ -0,0 +1,87 @@ +package com.thealgorithms.tree.AVLtree; + +public class AVLInsert { + + static class Node { + int key, height; + Node left, right; + + Node(int key) { + this.key = key; + height = 1; + } + } + + protected Node root; + + protected int height(Node node) { + return (node == null) ? 0 : node.height; + } + + protected int getBalance(Node node) { + return (node == null) ? 0 : height(node.left) - height(node.right); + } + + protected Node rightRotate(Node y) { + Node x = y.left; + Node 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; + } + + protected Node leftRotate(Node x) { + Node y = x.right; + Node 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; + } + + public Node insert(Node node, int key) { + if (node == null) { + return new Node(key); + } + + if (key < node.key) { + node.left = insert(node.left, key); + } else if (key > node.key) { + node.right = insert(node.right, key); + } else { + return node; // Duplicate keys not allowed + } + + node.height = 1 + Math.max(height(node.left), height(node.right)); + int balance = getBalance(node); + + if (balance > 1 && key < node.left.key) { + return rightRotate(node); + } + + if (balance < -1 && key > node.right.key) { + return leftRotate(node); + } + + if (balance > 1 && key > node.left.key) { + node.left = leftRotate(node.left); + return rightRotate(node); + } + + if (balance < -1 && key < node.right.key) { + node.right = rightRotate(node.right); + return leftRotate(node); + } + + return node; + } +} diff --git a/src/test/java/com/thealgorithms/tree/AVLtree/Rotations.java b/src/test/java/com/thealgorithms/tree/AVLtree/Rotations.java new file mode 100644 index 000000000000..76b438cddf75 --- /dev/null +++ b/src/test/java/com/thealgorithms/tree/AVLtree/Rotations.java @@ -0,0 +1,30 @@ +package com.thealgorithms.tree.AVLtree; + +public class Rotations extends AVLInsert { + + public Node rightRotate(Node y) { + Node x = y.left; + Node 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; + } + + public Node leftRotate(Node x) { + Node y = x.right; + Node 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; + } +}