AVL Tree in Data Structures

An AVL Tree is a self-balancing Binary Search Tree (BST). In a normal BST, the tree can become unbalanced, which makes searching slow. An AVL Tree solves this problem by automatically maintaining balance after every insertion or deletion.

Why do we need an AVL Tree?

Let’s understand the problem first. In a BST, if we insert values in sorted order, the tree may look like this:

10
  \
   20
     \
      30
        \
         40

This looks like a linked list, not a tree. Searching here becomes slow. An AVL Tree prevents this by rebalancing itself.

What does AVL mean?

AVL is named after its inventors: Adelson-Velsky and Landis. It was the first self-balancing BST.

AVL Tree Rule

  • It is a self-balancing Binary Search Tree.
  • For every node: Balance Factor = height(left)height(right) = −1, 0, or +1
  • If unbalanced, rotations are used to fix it.

(Height = longest path from a node to a leaf)

After Insertion or Deletion, if the balance factor becomes -2 or +2, rotations are applied.

Types of Rotations

  1. LL (Left–Left): Occurs when a node becomes unbalanced due to insertion in the left subtree of the left child – fixed by Right Rotation
  2. RR (Right–Right): Occurs when insertion is in the right subtree of the right child – fixed by Left Rotation
  3. LR (Left–Right): Occurs when insertion is in the right subtree of the left child – fixed by Left Rotation on the child, then Right Rotation
  4. RL (Right–Left): Occurs when insertion is in the left subtree of the right child – fixed by Right Rotation on the child, then Left Rotation

Why AVL Tree is Important?

  • Keeps the tree balanced automatically
  • Ensures fast searching, insertion, and deletion
  • Prevents the tree from becoming unbalanced
  • Guarantees O(log n) time complexity
  • Better performance than a normal Binary Search Tree in the worst case

AVL Tree Program in Java (Insertion + Traversal)

In this Java program, we insert values into an AVL Tree and print them using inorder traversal to verify the sorted structure.

// Node class for an AVL Tree
class Node {
    int data;
    int height;
    Node left;
    Node right;

    Node(int data) {
        this.data = data;
        height = 1;
    }
}

public class AVLTree {

    Node root;

    // Get height of node
    int height(Node node) {
        if (node == null)
            return 0;
        return node.height;
    }

    // Get balance factor
    int getBalance(Node node) {
        if (node == null)
            return 0;
        return height(node.left) - height(node.right);
    }

    // Right rotate
    Node rightRotate(Node y) {
        Node x = y.left;
        Node T2 = x.right;

        // 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;
    }

    // Left rotate
    Node leftRotate(Node x) {
        Node y = x.right;
        Node T2 = y.left;

        // 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;
    }

    // Insert into AVL Tree
    Node insert(Node node, int value) {

        // Normal BST insertion
        if (node == null)
            return new Node(value);

        if (value < node.data)
            node.left = insert(node.left, value);
        else if (value > node.data)
            node.right = insert(node.right, value);
        else
            return node; // no duplicates

        // Update height
        node.height = 1 + Math.max(height(node.left), height(node.right));

        // Get balance factor
        int balance = getBalance(node);

        // LL Case
        if (balance > 1 && value < node.left.data)
            return rightRotate(node);

        // RR Case
        if (balance < -1 && value > node.right.data)
            return leftRotate(node);

        // LR Case
        if (balance > 1 && value > node.left.data) {
            node.left = leftRotate(node.left);
            return rightRotate(node);
        }

        // RL Case
        if (balance < -1 && value < node.right.data) {
            node.right = rightRotate(node.right);
            return leftRotate(node);
        }

        return node;
    }

    // Inorder traversal
    void inorder(Node node) {
        if (node == null)
            return;

        inorder(node.left);
        System.out.print(node.data + " ");
        inorder(node.right);
    }

    // Main method
    public static void main(String[] args) {

        AVLTree tree = new AVLTree();

        int[] values = {10, 20, 30, 40, 50, 25};

        for (int val : values) {
            tree.root = tree.insert(tree.root, val);
        }

        System.out.print("Inorder Traversal: ");
        tree.inorder(tree.root); // Sorted output
    }
}

An AVL Tree is a self-balancing Binary Search Tree. It automatically keeps itself balanced after every insertion.