public class AVLTree {
private static Node root;
static Node insert(Node node, int data) {
if(node == null) {
return new Node(data);
} else if(data < node.data) {
node.left = insert(node.left, data);
} else if(data > node.data) {
node.right = insert(node.right, data);
}
node.height = getHeightOfNode(node);
if(getBalanceFactor(node) == 2) {
if(getBalanceFactor(node.left) == 1) {
return performLLRotation(node);
} else if(getBalanceFactor(node.left) == -1) {
return performLRRotation(node);
}
} else if(getBalanceFactor(node) == -2) {
if(getBalanceFactor(node.right) == -1) {
return performRRRotation(node);
} else if(getBalanceFactor(node.right) == 1) {
return performRLRotation(node);
}
}
return node;
}
static Node delete(Node node, int data) {
if(node == null) {
return null;
}
if(node.left == null && node.right == null) {
if(node == root) {
root = null;
}
return null;
}
if(data < node.data) {
node.left = delete(node.left, data);
} else if(data > node.data) {
node.right = delete(node.right, data);
} else {
Node inorderPredOrSucc = null;
if(getHeightOfNode(node.left) > getHeightOfNode(node.right)) {
inorderPredOrSucc = inorderPredecessor(node.left);
node.data = inorderPredOrSucc.data;
node.left = delete(node.left, inorderPredOrSucc.data);
} else {
inorderPredOrSucc = inorderSuccessor(node.right);
node.data = inorderPredOrSucc.data;
node.right = delete(node.right, inorderPredOrSucc.data);
}
}
node.height = getHeightOfNode(node);
if(getBalanceFactor(node) == 2) {
if(getBalanceFactor(node.left) == 1 || getBalanceFactor(node.left) == 0) {
return performLLRotation(node);
} else if(getBalanceFactor(node.left) == -1) {
return performLRRotation(node);
}
} else if(getBalanceFactor(node) == -2) {
if(getBalanceFactor(node.right) == -1 || getBalanceFactor(node.left) == 0) {
return performRRRotation(node);
} else if(getBalanceFactor(node.left) == 1) {
return performRLRotation(node);
}
}
return node;
}
static Node inorderPredecessor(Node node) {
while(node != null && node.right != null) {
node = node.right;
}
return node;
}
static Node inorderSuccessor(Node node) {
while(node != null && node.left != null) {
node = node.left;
}
return node;
}
static int getHeightOfNode(Node node) {
int leftHeight = node.left != null ? node.left.height : 0;
int rightHeight = node.right != null ? node.right.height : 0;
return (leftHeight > rightHeight ? leftHeight : rightHeight) + 1;
}
static int getBalanceFactor(Node node) {
int leftHeight = node.left != null ? node.left.height : 0;
int rightHeight = node.right != null ? node.right.height : 0;
return leftHeight - rightHeight;
}
static Node performLLRotation(Node node) {
Node newRoot = node.left;
node.left = newRoot.right;
newRoot.right = node;
node.height = getHeightOfNode(node);
newRoot.height = getHeightOfNode(newRoot);
if(root == node) {
root = newRoot;
}
return newRoot;
}
static Node performLRRotation(Node node) {
Node leftChild = node.left;
Node newRoot = leftChild.right;
leftChild.right = newRoot.left;
node.left = newRoot.right;
newRoot.left = leftChild;
newRoot.right = node;
leftChild.height = getHeightOfNode(leftChild);
node.height = getHeightOfNode(node);
newRoot.height = getHeightOfNode(newRoot);
if(root == node) {
root = newRoot;
}
return newRoot;
}
static Node performRRRotation(Node node) {
Node newRoot = node.right;
node.right = newRoot.left;
newRoot.left = node;
node.height = getHeightOfNode(node);
newRoot.height = getHeightOfNode(newRoot);
if(root == node) {
root = newRoot;
}
return newRoot;
}
static Node performRLRotation(Node node) {
Node rightChild = node.right;
Node newRoot = node.right.left;
node.right = newRoot.left;
rightChild.left = newRoot.right;
newRoot.left = node;
newRoot.right = rightChild;
node.height = getHeightOfNode(node);
rightChild.height = getHeightOfNode(rightChild);
newRoot.height = getHeightOfNode(newRoot);
if(root == node) {
root = newRoot;
}
return newRoot;
}
static void preOrderTraversal(Node root) {
if(root == null) {
return;
}
System.out.print(root.data + " ");
preOrderTraversal(root.left);
preOrderTraversal(root.right);
}
static void performAllRotations() {
root = insert(null, 50);
insert(root, 100);
insert(root, 30);
insert(root, 40);
insert(root, 20);
insert(root, 10);
System.out.println("Test Case LL Rotation : ");
preOrderTraversal(root);
root = insert(null, 50);
insert(root, 100);
insert(root, 30);
insert(root, 40);
insert(root, 45);
insert(root, 35);
insert(root, 20);
System.out.println("\nTest Case LR Rotation : ");
preOrderTraversal(root);
root = insert(null, 50);
insert(root, 25);
insert(root, 100);
insert(root, 60);
insert(root, 150);
insert(root, 200);
System.out.println("\nTest Case RR Rotation : ");
preOrderTraversal(root);
root = insert(null, 50);
insert(root, 25);
insert(root, 100);
insert(root, 150);
insert(root, 60);
insert(root, 65);
System.out.println("\nTest Case RL Rotation : ");
preOrderTraversal(root);
}
public static void main (String[] args) {
performAllRotations();
int[] array = new int[] {10, 20, 30, 25,28, 27, 5};
root = insert(null, array[0]);
for(int i = 1; i < array.length; i++) {
insert(root, array[i]);
}
System.out.println("\nCreate and print pre-order of AVL tree : ");
preOrderTraversal(root);
delete(root, 28);
System.out.println("After deleting 28 : ");
preOrderTraversal(root);
}
private static class Node {
int data;
int height;
Node left;
Node right;
public Node(int data) {
this.data = data;
this.height = 1;
}
}
}
Output
Test Case LL Rotation :
30 20 10 50 40 100
Test Case LR Rotation :
40 30 20 35 50 45 100
Test Case RR Rotation :
100 50 25 60 150 200
Test Case RL Rotation :
60 50 25 100 65 150
Create and print pre-order of AVL tree :
25 10 5 20 28 27 30 After deleting 28 :
25 10 5 20 30 27
Comments
Post a Comment