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 TreeAn 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:
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 TreeAVL 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:
- Database Indexing
- Memory Management
- File Systems
- Network Routing
- Priority Queues
- Compiler Design
- Geospatial Databases
- Event Scheduling Systems
- Artificial Intelligence and Machine Learning
- Telecommunication Systems
ConclusionIn 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.
|