import java.util.*;
public class Main {
static int rotations = 0;
static class Node {
int key;
Node left;
Node right;
int height;
Node(int key) {
this.key = key;
this.left = null;
this.right = null;
this.height = 1;
}
}
// Create a new node
public static Node createNode(int key) {
return new Node(key);
}
// Return stored height
public static int height(Node node) {
if (node == null)
return 0;
return node.height;
}
// Calculate balance factor
public static int getBalance(Node node) {
if (node == null)
return 0;
return height(node.left) - height(node.right);
}
// Right Rotation
public static Node rightRotate(Node y) {
rotations++;
Node x = y.left;
Node T2 = x.right;
// Rotation
x.right = y;
y.left = T2;
// Update heights
height(y.left),
height(y.right)
);
height(x.left),
height(x.right)
);
return x;
}
// Left Rotation
public static Node leftRotate(Node x) {
rotations++;
Node y = x.right;
Node T2 = y.left;
// Rotation
y.left = x;
x.right = T2;
// Update heights
height(x.left),
height(x.right)
);
height(y.left),
height(y.right)
);
return y;
}
// AVL Insertion
public static Node insert(Node node, int key) {
// 1. Normal BST insertion
if (node == null) {
return createNode(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
}
// 2. Update height
node.
height = 1 + Math.
max( height(node.left),
height(node.right)
);
// 3. Calculate balance factor
int balance = getBalance(node);
// 4. LL Case
if (balance > 1 && key < node.left.key) {
return rightRotate(node);
}
// 5. RR Case
if (balance < -1 && key > node.right.key) {
return leftRotate(node);
}
// 6. LR Case
if (balance > 1 && key > node.left.key) {
node.left = leftRotate(node.left);
return rightRotate(node);
}
// 7. RL Case
if (balance < -1 && key < node.right.key) {
node.right = rightRotate(node.right);
return leftRotate(node);
}
// Tree is already balanced
return node;
}
// Inorder traversal
public static void inorder(Node root) {
if (root == null)
return;
inorder(root.left);
root.key + "(" + root.height + ") "
);
inorder(root.right);
}
public static void main
(String[] args
) {
int[] arr = {
50, 30, 70, 20, 40, 60, 80,
10, 5, 15, 25, 27, 26, 65,
62, 64, 90, 100, 95
};
Node root = null;
for (int key : arr) {
root = insert(root, key);
}
System.
out.
println("Inorder traversal:"); inorder(root);
System.
out.
println("Total rotations = " + rotations
);
System.
out.
println("Root = " + root.
key); }
}
aW1wb3J0IGphdmEudXRpbC4qOwoKcHVibGljIGNsYXNzIE1haW4gewoKICAgIHN0YXRpYyBpbnQgcm90YXRpb25zID0gMDsKCiAgICBzdGF0aWMgY2xhc3MgTm9kZSB7CiAgICAgICAgaW50IGtleTsKICAgICAgICBOb2RlIGxlZnQ7CiAgICAgICAgTm9kZSByaWdodDsKICAgICAgICBpbnQgaGVpZ2h0OwoKICAgICAgICBOb2RlKGludCBrZXkpIHsKICAgICAgICAgICAgdGhpcy5rZXkgPSBrZXk7CiAgICAgICAgICAgIHRoaXMubGVmdCA9IG51bGw7CiAgICAgICAgICAgIHRoaXMucmlnaHQgPSBudWxsOwogICAgICAgICAgICB0aGlzLmhlaWdodCA9IDE7CiAgICAgICAgfQogICAgfQoKICAgIC8vIENyZWF0ZSBhIG5ldyBub2RlCiAgICBwdWJsaWMgc3RhdGljIE5vZGUgY3JlYXRlTm9kZShpbnQga2V5KSB7CiAgICAgICAgcmV0dXJuIG5ldyBOb2RlKGtleSk7CiAgICB9CgogICAgLy8gUmV0dXJuIHN0b3JlZCBoZWlnaHQKICAgIHB1YmxpYyBzdGF0aWMgaW50IGhlaWdodChOb2RlIG5vZGUpIHsKICAgICAgICBpZiAobm9kZSA9PSBudWxsKQogICAgICAgICAgICByZXR1cm4gMDsKCiAgICAgICAgcmV0dXJuIG5vZGUuaGVpZ2h0OwogICAgfQoKICAgIC8vIENhbGN1bGF0ZSBiYWxhbmNlIGZhY3RvcgogICAgcHVibGljIHN0YXRpYyBpbnQgZ2V0QmFsYW5jZShOb2RlIG5vZGUpIHsKICAgICAgICBpZiAobm9kZSA9PSBudWxsKQogICAgICAgICAgICByZXR1cm4gMDsKCiAgICAgICAgcmV0dXJuIGhlaWdodChub2RlLmxlZnQpIC0gaGVpZ2h0KG5vZGUucmlnaHQpOwogICAgfQoKICAgIC8vIFJpZ2h0IFJvdGF0aW9uCiAgICBwdWJsaWMgc3RhdGljIE5vZGUgcmlnaHRSb3RhdGUoTm9kZSB5KSB7CgogICAgICAgIHJvdGF0aW9ucysrOwoKICAgICAgICBOb2RlIHggPSB5LmxlZnQ7CiAgICAgICAgTm9kZSBUMiA9IHgucmlnaHQ7CgogICAgICAgIC8vIFJvdGF0aW9uCiAgICAgICAgeC5yaWdodCA9IHk7CiAgICAgICAgeS5sZWZ0ID0gVDI7CgogICAgICAgIC8vIFVwZGF0ZSBoZWlnaHRzCiAgICAgICAgeS5oZWlnaHQgPSAxICsgTWF0aC5tYXgoCiAgICAgICAgICAgIGhlaWdodCh5LmxlZnQpLAogICAgICAgICAgICBoZWlnaHQoeS5yaWdodCkKICAgICAgICApOwoKICAgICAgICB4LmhlaWdodCA9IDEgKyBNYXRoLm1heCgKICAgICAgICAgICAgaGVpZ2h0KHgubGVmdCksCiAgICAgICAgICAgIGhlaWdodCh4LnJpZ2h0KQogICAgICAgICk7CgogICAgICAgIHJldHVybiB4OwogICAgfQoKICAgIC8vIExlZnQgUm90YXRpb24KICAgIHB1YmxpYyBzdGF0aWMgTm9kZSBsZWZ0Um90YXRlKE5vZGUgeCkgewoKICAgICAgICByb3RhdGlvbnMrKzsKCiAgICAgICAgTm9kZSB5ID0geC5yaWdodDsKICAgICAgICBOb2RlIFQyID0geS5sZWZ0OwoKICAgICAgICAvLyBSb3RhdGlvbgogICAgICAgIHkubGVmdCA9IHg7CiAgICAgICAgeC5yaWdodCA9IFQyOwoKICAgICAgICAvLyBVcGRhdGUgaGVpZ2h0cwogICAgICAgIHguaGVpZ2h0ID0gMSArIE1hdGgubWF4KAogICAgICAgICAgICBoZWlnaHQoeC5sZWZ0KSwKICAgICAgICAgICAgaGVpZ2h0KHgucmlnaHQpCiAgICAgICAgKTsKCiAgICAgICAgeS5oZWlnaHQgPSAxICsgTWF0aC5tYXgoCiAgICAgICAgICAgIGhlaWdodCh5LmxlZnQpLAogICAgICAgICAgICBoZWlnaHQoeS5yaWdodCkKICAgICAgICApOwoKICAgICAgICByZXR1cm4geTsKICAgIH0KCiAgICAvLyBBVkwgSW5zZXJ0aW9uCiAgICBwdWJsaWMgc3RhdGljIE5vZGUgaW5zZXJ0KE5vZGUgbm9kZSwgaW50IGtleSkgewoKICAgICAgICAvLyAxLiBOb3JtYWwgQlNUIGluc2VydGlvbgogICAgICAgIGlmIChub2RlID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZU5vZGUoa2V5KTsKICAgICAgICB9CgogICAgICAgIGlmIChrZXkgPCBub2RlLmtleSkgewogICAgICAgICAgICBub2RlLmxlZnQgPSBpbnNlcnQobm9kZS5sZWZ0LCBrZXkpOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChrZXkgPiBub2RlLmtleSkgewogICAgICAgICAgICBub2RlLnJpZ2h0ID0gaW5zZXJ0KG5vZGUucmlnaHQsIGtleSk7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICByZXR1cm4gbm9kZTsgLy8gRHVwbGljYXRlIGtleXMKICAgICAgICB9CgogICAgICAgIC8vIDIuIFVwZGF0ZSBoZWlnaHQKICAgICAgICBub2RlLmhlaWdodCA9IDEgKyBNYXRoLm1heCgKICAgICAgICAgICAgaGVpZ2h0KG5vZGUubGVmdCksCiAgICAgICAgICAgIGhlaWdodChub2RlLnJpZ2h0KQogICAgICAgICk7CgogICAgICAgIC8vIDMuIENhbGN1bGF0ZSBiYWxhbmNlIGZhY3RvcgogICAgICAgIGludCBiYWxhbmNlID0gZ2V0QmFsYW5jZShub2RlKTsKCiAgICAgICAgLy8gNC4gTEwgQ2FzZQogICAgICAgIGlmIChiYWxhbmNlID4gMSAmJiBrZXkgPCBub2RlLmxlZnQua2V5KSB7CiAgICAgICAgICAgIHJldHVybiByaWdodFJvdGF0ZShub2RlKTsKICAgICAgICB9CgogICAgICAgIC8vIDUuIFJSIENhc2UKICAgICAgICBpZiAoYmFsYW5jZSA8IC0xICYmIGtleSA+IG5vZGUucmlnaHQua2V5KSB7CiAgICAgICAgICAgIHJldHVybiBsZWZ0Um90YXRlKG5vZGUpOwogICAgICAgIH0KCiAgICAgICAgLy8gNi4gTFIgQ2FzZQogICAgICAgIGlmIChiYWxhbmNlID4gMSAmJiBrZXkgPiBub2RlLmxlZnQua2V5KSB7CiAgICAgICAgICAgIG5vZGUubGVmdCA9IGxlZnRSb3RhdGUobm9kZS5sZWZ0KTsKICAgICAgICAgICAgcmV0dXJuIHJpZ2h0Um90YXRlKG5vZGUpOwogICAgICAgIH0KCiAgICAgICAgLy8gNy4gUkwgQ2FzZQogICAgICAgIGlmIChiYWxhbmNlIDwgLTEgJiYga2V5IDwgbm9kZS5yaWdodC5rZXkpIHsKICAgICAgICAgICAgbm9kZS5yaWdodCA9IHJpZ2h0Um90YXRlKG5vZGUucmlnaHQpOwogICAgICAgICAgICByZXR1cm4gbGVmdFJvdGF0ZShub2RlKTsKICAgICAgICB9CgogICAgICAgIC8vIFRyZWUgaXMgYWxyZWFkeSBiYWxhbmNlZAogICAgICAgIHJldHVybiBub2RlOwogICAgfQoKICAgIC8vIElub3JkZXIgdHJhdmVyc2FsCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgaW5vcmRlcihOb2RlIHJvb3QpIHsKCiAgICAgICAgaWYgKHJvb3QgPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICBpbm9yZGVyKHJvb3QubGVmdCk7CgogICAgICAgIFN5c3RlbS5vdXQucHJpbnQoCiAgICAgICAgICAgIHJvb3Qua2V5ICsgIigiICsgcm9vdC5oZWlnaHQgKyAiKSAiCiAgICAgICAgKTsKCiAgICAgICAgaW5vcmRlcihyb290LnJpZ2h0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CgogICAgICAgIGludFtdIGFyciA9IHsKICAgICAgICAgICAgNTAsIDMwLCA3MCwgMjAsIDQwLCA2MCwgODAsCiAgICAgICAgICAgIDEwLCA1LCAxNSwgMjUsIDI3LCAyNiwgNjUsCiAgICAgICAgICAgIDYyLCA2NCwgOTAsIDEwMCwgOTUKICAgICAgICB9OwoKICAgICAgICBOb2RlIHJvb3QgPSBudWxsOwoKICAgICAgICBmb3IgKGludCBrZXkgOiBhcnIpIHsKICAgICAgICAgICAgcm9vdCA9IGluc2VydChyb290LCBrZXkpOwogICAgICAgIH0KCiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJJbm9yZGVyIHRyYXZlcnNhbDoiKTsKICAgICAgICBpbm9yZGVyKHJvb3QpOwoKICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKCiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJUb3RhbCByb3RhdGlvbnMgPSAiICsgcm90YXRpb25zKTsKCiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJSb290ID0gIiArIHJvb3Qua2V5KTsKICAgIH0KfQ==