Horje
AVL Tree program in Java

AVL tree stands for Adelson-Velsky and Landis tree. An AVL tree is a type of self-balancing binary 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 the maintaining tree’s height to the O(log n) which is ensure efficient operations such as search operation, insertion operation and deletion operation.

Organization of an AVL Tree

An AVL tree is the 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 subtree differ 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 d) {
        key = d;
        height = 1;
    }
}

class AVLTree {

    Node root;

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

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

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

        // Perform rotation
        x.right = y;
        y.left = T2;

        // Update heights
        y.height = max(height(y.left), height(y.right)) + 1;
        x.height = max(height(x.left), height(x.right)) + 1;

        // Return new root
        return x;
    }

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

        // Perform rotation
        y.left = x;
        x.right = T2;

        // Update heights
        x.height = max(height(x.left), height(x.right)) + 1;
        y.height = max(height(y.left), height(y.right)) + 1;

        // Return new root
        return y;
    }

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

    // Insert a key into the subtree rooted with node
      // and returns the new root of the subtree
    Node insert(Node node, int key) {
        // Perform the normal BST insertion
        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 // Duplicate keys not allowed
            return node;

        // Update height of this ancestor node
        node.height = 1 + max(height(node.left), height(node.right));

        // Get the balance factor of this ancestor node
          // to check whether this node became unbalanced
        int balance = getBalance(node);

        // If this node becomes unbalanced, then there are 4 cases

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

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

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

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

        // Return the (unchanged) node pointer
        return node;
    }

    // Utility function to print preorder traversal of the tree
    void preOrder(Node node) {
        if (node != null) {
            System.out.print(node.key + " ");
            preOrder(node.left);
            preOrder(node.right);
        }
    }

    // Utility function to print inorder traversal of the tree
    void inOrder(Node node) {
        if (node != null) {
            inOrder(node.left);
            System.out.print(node.key + " ");
            inOrder(node.right);
        }
    }

    // Utility function to print postorder traversal of the tree
    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();

        // Insert nodes
        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);

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

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

        // Print postorder traversal of the tree
        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.




Reffered: https://www.geeksforgeeks.org


Java

Related
Java Program to Construct K-D Tree Java Program to Construct K-D Tree
Java Program to Implement Fibonacci Heap Java Program to Implement Fibonacci Heap
Huffman Coding Java Huffman Coding Java
Balanced Binary Tree in Java Balanced Binary Tree in Java
Adding JGit to the Project with Maven Adding JGit to the Project with Maven

Type:
Geek
Category:
Coding
Sub Category:
Tutorial
Uploaded by:
Admin
Views:
15