Open In App

AVL Tree program in Java

Last Updated : 04 Apr, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

AVL tree stands for Adelson-Velsky and Landis tree. An AVL tree is a type of self-balancing binary search tree. In an AVL tree, the height of two child subtrees of any of the nodes differs by no more than one, ensuring that the tree remains balanced. This property helps in maintaining the tree's height to O(log n), which ensures efficient operations such as search operation, insertion operation, and deletion operation.

Organization of an AVL Tree

An AVL tree is a type of binary search tree (BST) that maintains its balance through rotations. The key feature of the AVL tree is that for any given node, the height of the left and right subtrees differs by no more than one. This ensures that the tree remains balanced and allows for efficient operations.

Representation of an AVL Tree:

AVL_Tree


Explanation of the Image:

In the above image, an AVL tree is organized to the maintain balance through use of heights and rotations. The key operations are ensure that height difference between subtree of any node is at most one which is keep the tree balanced and operations efficient. Rotations are plays the crucial role in the maintaining this balance after insertion and deletion.

Implementation of an AVL Tree

Java
// Java Program to Implement AVL Tree

class Node {
    int key, height;
    Node left, right;

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

class AVLTree {

    Node root;

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

    // Get maximum of two integers
    int max(int a, int b) {
        return (a > b) ? a : b;
    }

    // Right rotate subtree rooted with node
    Node rightRotate(Node node) {
        Node leftChild = node.left;
        Node temp = leftChild.right;

        // Perform rotation
        leftChild.right = node;
        node.left = temp;

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

        // Return new root
        return leftChild;
    }

    // Left rotate subtree rooted with node
    Node leftRotate(Node node) {
        Node rightChild = node.right;
        Node temp = rightChild.left;

        // Perform rotation
        rightChild.left = node;
        node.right = temp;

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

        // Return new root
        return rightChild;
    }

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

    // Insert a key into the AVL tree and return the new root of the subtree
    Node insert(Node root, int key) {
        if (root == null)
            return new Node(key);

        if (key < root.key)
            root.left = insert(root.left, key);
        else if (key > root.key)
            root.right = insert(root.right, key);
        else
            return root;

        // Update height of root
        root.height = 1 + max(height(root.left), height(root.right));

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

        // Left Left Case
        if (balance > 1 && key < root.left.key)
            return rightRotate(root);

        // Right Right Case
        if (balance < -1 && key > root.right.key)
            return leftRotate(root);

        // Left Right Case
        if (balance > 1 && key > root.left.key) {
            root.left = leftRotate(root.left);
            return rightRotate(root);
        }

        // Right Left Case
        if (balance < -1 && key < root.right.key) {
            root.right = rightRotate(root.right);
            return leftRotate(root);
        }

        return root;
    }

    // Utility functions for traversal
    void preOrder(Node node) {
        if (node != null) {
            System.out.print(node.key + " ");
            preOrder(node.left);
            preOrder(node.right);
        }
    }

    void inOrder(Node node) {
        if (node != null) {
            inOrder(node.left);
            System.out.print(node.key + " ");
            inOrder(node.right);
        }
    }

    void postOrder(Node node) {
        if (node != null) {
            postOrder(node.left);
            postOrder(node.right);
            System.out.print(node.key + " ");
        }
    }

    public static void main(String[] args) {
        AVLTree tree = new AVLTree();

        tree.root = tree.insert(tree.root, 10);
        tree.root = tree.insert(tree.root, 20);
        tree.root = tree.insert(tree.root, 30);
        tree.root = tree.insert(tree.root, 40);
        tree.root = tree.insert(tree.root, 50);
        tree.root = tree.insert(tree.root, 25);

        System.out.println("Preorder traversal of constructed AVL tree is : ");
        tree.preOrder(tree.root);
        System.out.println();

        System.out.println("Inorder traversal of constructed AVL tree is : ");
        tree.inOrder(tree.root);
        System.out.println();

        System.out.println("Postorder traversal of constructed AVL tree is : ");
        tree.postOrder(tree.root);
        System.out.println();
    }
}

Output:

Preorder traversal of constructed AVL tree is : 
30 20 10 25 40 50
Inorder traversal of constructed AVL tree is :
10 20 25 30 40 50
Postorder traversal of constructed AVL tree is :
10 25 20 50 40 30


Complexity of the Above Methods

Operations

Explanation

Complexity

Insertion Operation

Insertion operation in AVL tree is involved the binary search tree insertion followed by the re-balanced the tree if it is become unbalanced.

The time complexity of insertion operation is O(log n).
The space complexity of insertion operation is O(1).

Deletion Operation

Deletion operation from the AVL tree is involved the balanced search tree deletion followed by the re-balancing tree if it is becomes unbalanced.

The time complexity of deletion operation is O(log n).
The space complexity of deletion operation is O(1).

Search Operation

Searching operation is involved the searching for the node in the AVL tree is identical to the searching in the BST.

The time complexity of search operation is O(log n).
The space complexity of search operation is O(1).

Traversal Operation

AVL trees supports the standard tree traversal methods such as preorder, inorder and postorder traversals.

The time complexity of traversal operation is O(n).
The space complexity of traversal operation is O(log n).

Applications of an AVL Tree

AVL trees are being balanced binary search trees, it have several practical applications in the computer science and real-world scenarios where the efficient data retrieval and updates are crucial. Here is the some applications of AVL Tree:

  1. Database Indexing
  2. Memory Management
  3. File Systems
  4. Network Routing
  5. Priority Queues
  6. Compiler Design
  7. Geospatial Databases
  8. Event Scheduling Systems
  9. Artificial Intelligence and Machine Learning
  10. Telecommunication Systems

Conclusion

In conclusion, AVL trees are the powerful and versatile data structures that is ensure the efficient and balanced management of the dynamically changing the datasets. Their ability to the maintain the balanced binary search tree guarantees O(log n) time complexity for the insertion operation, deletion operation and search operation and it make them highly suitable for the applications are requiring the frequently updates and fast access times. From the database indexing and memory management to the file systems and network routing. AVL trees are crucial role in the optimizing performance and ensuring the data integrity across the various domains.


Next Article
Article Tags :
Practice Tags :

Similar Reads