AVL Tree
An AVL Tree is a Binary Search Tree that is always balanced. Every node has a balance factor (height of left subtree - height of right subtree) of -1, 0, or 1. If the balance factor deviates from this, a rotation is performed.
Balance Factor
def height(node):
if not node:
return 0
return node.height
def balance_factor(node):
if not node:
return 0
return height(node.left) - height(node.right)
Rotations
1. RR Rotation (left)
Occurs when the right subtree is too heavy.
y x
/ \ / \
A x => y C
/ \ / \
B C A B
2. LL Rotation (right)
Occurs when the left subtree is too heavy.
y x
/ \ / \
x C => A y
/ \ / \
A B B C
3. LR Rotation
Left rotation on the left child, then right rotation.
4. RL Rotation
Right rotation on the right child, then left rotation.
Implementation
class AVLNode:
def __init__(self, val):
self.val = val
self.left = None
self.right = None
self.height = 1
class AVLTree:
def insert(self, root, val):
if not root:
return AVLNode(val)
if val < root.val:
root.left = self.insert(root.left, val)
elif val > root.val:
root.right = self.insert(root.right, val)
else:
return root
root.height = 1 + max(height(root.left), height(root.right))
bf = balance_factor(root)
# LL
if bf > 1 and val < root.left.val:
return self._right_rotate(root)
# RR
if bf < -1 and val > root.right.val:
return self._left_rotate(root)
# LR
if bf > 1 and val > root.left.val:
root.left = self._left_rotate(root.left)
return self._right_rotate(root)
# RL
if bf < -1 and val < root.right.val:
root.right = self._right_rotate(root.right)
return self._left_rotate(root)
return root
def _left_rotate(self, z):
y = z.right
T2 = y.left
y.left = z
z.right = T2
z.height = 1 + max(height(z.left), height(z.right))
y.height = 1 + max(height(y.left), height(y.right))
return y
def _right_rotate(self, z):
y = z.left
T3 = y.right
y.right = z
z.left = T3
z.height = 1 + max(height(z.left), height(z.right))
y.height = 1 + max(height(y.left), height(y.right))
return y
Why Are AVL Trees Important?
| Aspect | Plain BST | AVL Tree |
|---|---|---|
| Worst-case height | O(n) | O(log n) |
| Search | O(n) worst case | O(log n) guaranteed |
| Insert | O(n) worst case | O(log n) guaranteed |
| Rotations per insert | 0 | At most 2 |
AVL Trees enforce a stricter balance than Red-Black Trees.