AVL Tree is a self-balancing extension of L10 BST. All BST operations apply, plus rotations to maintain h = O(log N).
Step 1: Augment
- in every vertex x, we also store its height: x.height
- during insertion and deletion, we also update height
- height update can be added in insert() before the return
- size can be updated the same
Step 2: Define Invariant
- a vertex x is said to be height-balanced if
- a BST is said to be height-balanced if every vertex in the tree is height-balanced
Step 3: Maintain Height-Balance
- bf(x) = x.left.height - x.right.height
- aft insertion, from insertion point, check bf of each vertex up to the root
- once we have vertex with bf +2 or -2, have to rebalance it
Tree Rotations


Vertex rotateLeft(Vertex T) {
Vertex w = T.right;
w.parent = T.parent;
T.parent = w;
T.right = w.left;
if (w.left != null) {
w.left.parent = T;
}
w.left = T;
// update heights and sizes
// update height of T then W
w.size = T.size;
updateHeight(T);
updateSize(T);
updateHeight(w);
return w;
}
Vertex rotateRight(Vertex T) {
Vertex w = T.left;
w.parent = T.parent;
T.parent = w;
T.left = w.right;
if (w.right != null) {
w.right.parent = T;
}
w.right = T;
// same from here
}

Insertion / Deletion
- insert / delete key as in normal BST
- walk up the AVL tree from the insertion / deletion point to root
- at every step, update height and check bf
- if vertex out of balance (+2 / -2), use rotations to rebalance
- Insertion: only trigger one of the four cases once
- Deletion: may trigger one of the four cases several times, up to h = log N times




// recursive function to insert a new key in the AVL tree
Vertex insert(Vertex T, String v) {
// normal BST insertion
if (T == null) { // insertion point is found
return new Vertex(v);
}
if (T.key.compareTo(v) < 0) {
// search to the right
T.right = insert(T.right, v);
T.right.parent = T;
} else if (T.key.compareTo(v) > 0) {
// search to the left
T.left = insert(T.left, v);
T.left.parent = T;
} else { // duplicate
return T;
}
// update height and size of node
updateHeight(T);
updateSize(T);
// check balance factor and balance tree
int bf = balanceFactor(T);
// possible cases
if (bf > 1) {
// Left Right
if (balanceFactor(T.left) < 0) {
T.left = rotateLeft(T.left);
}
// Left Left
T = rotateRight(T);
}
if (bf < -1) {
// Right Left
if (balanceFactor(T.right) > 0) {
T.right = rotateRight(T.right);
}
// Right Right
T = rotateLeft(T);
}
return T;
}
-
starting LR / LL
- bf(x) = -2, -1 ≤ bf(x.left) ≤ 0 (LL)
- rightRotate(x)
- bf(x) = +2, bf(x.left) = -1 (LR)
- leftRotate(x.left)
- rightRotate(x)
- bf(x) = -2, -1 ≤ bf(x.left) ≤ 0 (LL)
-
starting RL / RR
- bf(x) = -2, -1 ≤ bf(x.right) ≤ 0 (RR)
- leftRotate(x)
- bf(x) = +2, bf(x.right) = 1 (RL)
- rightRotate(x.right)
- leftRotate(x)
Rotation stuff: (AVL)


- bf(x) = -2, -1 ≤ bf(x.right) ≤ 0 (RR)
