-
Hajipur, Bihar, 844101
An AVL tree is a self-balancing binary search tree. It keeps the height difference between the left and right subtrees within a safe limit so that searching, inserting and deleting values always stay fast. A normal binary search tree can become unbalanced if too many values fall on one side. This causes slow lookups. AVL trees fix this by rotating nodes whenever the balance breaks. Because of this, AVL trees are widely used in databases, indexing systems, dictionaries and applications that need consistent performance.
In this tutorial, you will learn what an AVL tree is, how balancing works, how rotations fix imbalance, how to insert and delete values and how to write a complete AVL tree implementation in Python. You will also learn real-life uses and step-by-step examples that help build clarity.
An AVL tree is a binary search tree with an extra rule:
The height difference between the left and right subtrees of any node must be at most 1.
This height difference is called the balance factor:
Balance Factor = height(left subtree) - height(right subtree)
Valid balance factors are -1, 0 and 1.
If the balance goes outside this range, the tree rotates and fixes itself.
The name comes from its inventors: Adelson-Velsky and Landis.
AVL trees are helpful because they guarantee:
Predictable performance
O(log n) search time
Fast insertions and deletions
Automatic self-balancing
These trees are used in indexing, memory management and structured data systems.
Rotations fix imbalance. There are four types:
Used when the right subtree is too heavy.
Used when the left subtree is too heavy.
When left child is right-heavy.
When right child is left-heavy.
These rotations restructure the tree while keeping the BST property intact.
Let’s start with a node structure:
class Node:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
self.height = 1
Each node stores its value, references to children and its height.
def get_height(node):
if not node:
return 0
return node.height
def get_balance(node):
if not node:
return 0
return get_height(node.left) - get_height(node.right)
These functions help detect imbalances.
def rotate_right(y):
x = y.left
temp = x.right
x.right = y
y.left = temp
y.height = 1 + max(get_height(y.left), get_height(y.right))
x.height = 1 + max(get_height(x.left), get_height(x.right))
return x
def rotate_left(x):
y = x.right
temp = y.left
y.left = x
x.right = temp
x.height = 1 + max(get_height(x.left), get_height(x.right))
y.height = 1 + max(get_height(y.left), get_height(y.right))
return y
These operations keep the tree balanced.
The insertion works like a normal BST. After inserting, you calculate the balance factor and apply the necessary rotation.
def insert(root, value):
if not root:
return Node(value)
if value < root.value:
root.left = insert(root.left, value)
else:
root.right = insert(root.right, value)
root.height = 1 + max(get_height(root.left), get_height(root.right))
balance = get_balance(root)
# Left Left Case
if balance > 1 and value < root.left.value:
return rotate_right(root)
# Right Right Case
if balance < -1 and value > root.right.value:
return rotate_left(root)
# Left Right Case
if balance > 1 and value > root.left.value:
root.left = rotate_left(root.left)
return rotate_right(root)
# Right Left Case
if balance < -1 and value < root.right.value:
root.right = rotate_right(root.right)
return rotate_left(root)
return root
This ensures the AVL properties stay intact.
Deletion also behaves like a normal BST. After removing the node, the tree checks for imbalance and rotates accordingly.
Here is a simple structure for deletion:
def find_min(node):
while node.left:
node = node.left
return node
def delete(root, value):
if not root:
return root
if value < root.value:
root.left = delete(root.left, value)
elif value > root.value:
root.right = delete(root.right, value)
else:
if not root.left:
return root.right
if not root.right:
return root.left
temp = find_min(root.right)
root.value = temp.value
root.right = delete(root.right, temp.value)
root.height = 1 + max(get_height(root.left), get_height(root.right))
balance = get_balance(root)
# Left Left Case
if balance > 1 and get_balance(root.left) >= 0:
return rotate_right(root)
# Left Right Case
if balance > 1 and get_balance(root.left) < 0:
root.left = rotate_left(root.left)
return rotate_right(root)
# Right Right Case
if balance < -1 and get_balance(root.right) <= 0:
return rotate_left(root)
# Right Left Case
if balance < -1 and get_balance(root.right) > 0:
root.right = rotate_right(root.right)
return rotate_left(root)
return root
def inorder(node):
if node:
inorder(node.left)
print(node.value)
inorder(node.right)
AVL inorder traversal always gives sorted results.
root = None
values = [20, 4, 15, 70, 50, 80, 30]
for v in values:
root = insert(root, v)
inorder(root)
This builds a balanced tree regardless of insertion order.
Fast and predictable access to records.
Balanced structures help manage free blocks.
Syntax trees remain well-structured.
Ordering and balancing help lookup speed.
Many dictionary-like structures use self-balancing trees.
AVL trees shine in systems where consistent fast performance is required.
root = insert(None, 10)
for v in [5, 3, 8]:
root = insert(root, v)
root = delete(root, 5)
inorder(root)
print(root.height)
Try adding sorted numbers and see it stays balanced.
AVL usually avoids duplicates manually.
for i in range(100):
root = insert(root, i)
Test cases where rotation happens.
Use traversal to understand balance.
An AVL tree is a self-balancing BST that ensures the height difference between subtrees always stays within limits. This keeps searching, inserting and deleting operations fast and reliable. You learned how balance factors work, how rotations fix imbalance, how to insert and delete values and how to build a full AVL tree implementation in Python. AVL trees appear in databases, search systems and structured data tools where stable performance is important.
Q1. Write a Python program to create an AVL Tree using values: 50, 30, 70, 20, 40.
Q2. Write a Python program to insert value 25 and check if the tree balances itself.
Q3. Write a Python program to perform and print Inorder traversal of the AVL Tree.
Q4. Write a Python program to modify your AVL Tree code to count the total number of nodes.
Q5. Write a Python program to display the balance factor of each node during insertions.
Q6. Write a Python program to perform a right rotation manually and print the updated tree.
Q7. Write a Python program to add print statements inside rotation functions to trace when and what type of rotation happens.
Q8. Write a Python program to delete a node from the AVL Tree and ensure it remains balanced.
Q9. Write a Python program to compare basic insertion time between an AVL Tree and a regular BST.
Q10. Write a Python program to count and print the number of leaf nodes in the AVL Tree.