AVL Tree
An AVL tree is a selfbalancing binary search tree where the heights of the two child subtrees of any node differ by at most one. This ensures worstcase O(log n) time for search, insert and delete.
Java example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 class AVLNode {
int height;
int value;
AVLNode left;
AVLNode right;
}
// Rotation helpers
AVLNode leftRotate(AVLNode x) {
AVLNode y = x.right;
x.right = y.left;
y.left = x;
x.height = max(height(x.left), height(x.right)) + 1;
y.height = max(height(y.left), height(y.right)) + 1;
return y;
}

C++ example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 struct AVLNode {
int height;
int value;
AVLNode *left;
AVLNode *right;
};
// Get node height
int height(AVLNode* node) {
if (!node) {
return 0;
}
return node>height;
}
// Rebalance on insert
void rebalance(AVLNode* &node) {
int balance = height(node>left)  height(node>right);
if (balance > 1) {
// Left heavy  rotate
if (height(node>left>left) > height(node>left>right)) {
// Left Left
node = rightRotate(node);
} else {
// Left Right
node>left = leftRotate(node>left);
node = rightRotate(node);
}
}
}

Python example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 class AVLNode:
def __init__(self, value):
self.value = value
self.height = 1
self.left = None
self.right = None
# Update height
def update_height(node):
node.height = max(height(node.left), height(node.right)) + 1
# Rebalance
def rebalance(node):
# Left heavy
if height(node.left)  height(node.right) > 1:
# Left left case
if height(node.left.left) > height(node.left.right):
return right_rotate(node)
# Left right case
else:
node.left = left_rotate(node.left)
return right_rotate(node)
# Right heavy
elif height(node.right)  height(node.left) > 1:
# Code mirrors left heavy logic
return node

AVL trees provide guaranteed O(log n) times for dynamic operations by maintaining balance. Useful for timecritical applications like realtime systems.
An AVL tree is a heightbalanced binary search tree. In an AVL tree, the difference between the heights of the right subtree and left subtree of every node is either 1, 0, or 1. The difference between the heights of the subtree is maintained by a factor named as balance factor. When inserting a new key in an AVL tree, you first compare the key with root. If the key is greater than root, then it is greater than all the nodes in left subtree of root. AVL trees remain balanced by four kinds of rotations during insertion or deletion. The rotation you choose is based on the position relationship of the unbalanced node and the inserted node. AVL trees have an advantage over binary search trees because they guarantee that the maximum time complexity for all the operations will never exceed O(logN).
AVL trees are a type of selfbalancing binary search tree. They are often used for inmemory sorts of sets and dictionaries. They are also used in database applications where there are frequent data lookups.
Here are some LeetCode problems that can be solved using AVL trees:
Count of Smaller Numbers After Self
This problem can be solved using an AVL tree with a time complexity of O(nLogn).
Find Median from Data Stream
This problem can be solved using an AVL tree with a 93.1% faster and 100% less Java solution.
AVL trees are faster than BST trees because they are selfbalancing and have a height that is as small as possible. The worstcase time complexity of all operations for an AVL tree is O(log N), while for a BST it is O(N).
AVL trees are a type of selfbalancing binary search tree. They have the ability to rebalance themselves, which makes them faster in the worst case. AVL trees guarantee a performance of O(logN) in the worst case for all operations, including insertion, deletion, and searching. In a binary search tree (BST), the value of the left node must be smaller than the parent node, and the value of the right node must be greater than the parent node. If values are inserted in a decreasing or increasing order, the BST will be one sided and the search time will be O(n). However, if you use an AVL tree, the tree will balance itself using rotations. Insertion and deletion are complex in an AVL tree because it requires multiple rotations to balance the tree. In a BST, insertion and deletion are easy because no rotations are required.
AVL Tree
An AVL (AdelsonVelsky and Landis) tree is a type of binary search tree that selfbalances. In an AVL tree, the heights of the two child subtrees of every node differ by at most one. If they differ by more than one at any time, rebalancing is done through rotations. This ensures that the tree remains approximately balanced, resulting in O(log n) time complexity for search, insert, and delete operations.
Java Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
 class Node {
int key, height;
Node left, right;
Node(int key) {
this.key = key;
this.height = 1; // height of new node is set to 1
}
}
class AVLTree {
Node root;
int height(Node node) {
return (node == null) ? 0 : node.height;
}
int balanceFactor(Node node) {
return (node == null) ? 0 : height(node.left)  height(node.right);
}
Node rotateRight(Node y) {
Node x = y.left;
Node T2 = x.right;
x.right = y;
y.left = T2;
y.height = Math.max(height(y.left), height(y.right)) + 1;
x.height = Math.max(height(x.left), height(x.right)) + 1;
return x;
}
// Similar logic applies for rotateLeft
// ...
// Insert and balance tree
Node insert(Node node, int key) {
// Standard BST insert
// ...
// Update height and balance tree
node.height = Math.max(height(node.left), height(node.right)) + 1;
int balance = balanceFactor(node);
// Perform rotations
if (balance > 1 && key < node.left.key)
return rotateRight(node);
// Other cases
// ...
return node;
}
}

In Java, we define an AVL tree using a Node
class that holds the key, height, and left and right children. The main AVLTree
class contains methods for rotations and balancing the tree.
C++ Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 struct Node {
int key, height;
Node *left, *right;
Node(int key) : key(key), height(1), left(nullptr), right(nullptr) {}
};
class AVLTree {
public:
Node* root;
int height(Node* node) {
return (node == nullptr) ? 0 : node>height;
}
int balanceFactor(Node* node) {
return (node == nullptr) ? 0 : height(node>left)  height(node>right);
}
Node* rotateRight(Node* y) {
Node* x = y>left;
Node* T2 = x>right;
x>right = y;
y>left = T2;
// Update heights and return new root
// ...
return x;
}
// Insert and balance tree
Node* insert(Node* node, int key) {
// Standard BST insert
// ...
// Update height and balance tree
// ...
}
};

In C++, we similarly define a Node
struct and an AVLTree
class. The class methods for rotations and balancing mirror the Java implementation.
Python Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 class Node:
def __init__(self, key):
self.key = key
self.height = 1
self.left = None
self.right = None
class AVLTree:
def __init__(self):
self.root = None
def height(self, node):
return 0 if node is None else node.height
def balance_factor(self, node):
return 0 if node is None else self.height(node.left)  self.height(node.right)
def rotate_right(self, y):
x = y.left
T2 = x.right
x.right = y
y.left = T2
# Update heights and return new root
# ...
def insert(self, root, key):
# Standard BST insert
# ...
# Update height and balance tree
# ...

In Python, the Node
class and AVLTree
class are quite straightforward. We define methods for rotations and balancing like in Java and C++.
AVL Trees are a crucial data structure for many applications where quick data retrieval is necessary. They optimize the tree balancing to ensure quick operations, and are used in databases, file systems, and other systems that require fast data access.