AVL Search Tree
AVL Search Tree
Data Structures
Lecture: AVL Tree
Motivation
• When building a binary search tree, what type of trees
would we like? Example: 3, 5, 8, 20, 18, 13, 22
3
5 13
8
5 20
13
18 3 8 18 22
20
22
2
• Complete binary tree is hard to build when we allow dynamic insert
and remove.
– We want a tree that has the following properties
• Tree height = O(log(N))
• allows dynamic insert and remove with O(log(N)) time
complexity.
– The AVL tree is one of this kind of trees.
8
13
5 18
5 20
3 13 20
3 8 18 22 22
3
AVL (Adelson-Velskii and Landis) Trees
• An AVL Tree is a
binary search tree such
that for every internal
node v of T, the heights
of the children of v can
differ by at most 1.
5
Which is an AVL Tree?
6
Balance Condition Violation
• If condition violated after a node insertion
– Which nodes do we need to rotate?
– Only nodes on path from insertion point to root may have their
balance altered
• Rebalance the tree through rotation at the deepest node with balance
violated
– The entire tree will be rebalanced
8
Single Rotation (Case 1)
9
Example
• After inserting 6
– Balance condition at node 8 is violated
10
Example
• Inserting 3, 2, 1, and then 4 to 7 sequentially into empty AVL tree
3
2
2
1 3
1
11
• Inserting 4 2
1 3
4
• Inserting 5
2 2
1 3 4
1
4 5
3
5
12
• Inserting 6 4
2
2 5
1 4
1 3 6
3 5
• Inserting 7
6
4 4
2 6
2 5
6 1 3 5 7
1 3
7
13
Example
• Inserting 16 and 15
4
4
2 6
2 6
1 3 5 15
1 3 5 7
7 16
16
15
14
Blank
15
• Inserting 14
4
4
2 6 2 7
15 1 3 6 15
1 3 5
7 16 5 14 16
14
16
Blank
17
// AVL tree implementation in C // Right rotate
struct Node *rightRotate(struct Node *y) {
#include <stdio.h> struct Node *x = y->left;
#include <stdlib.h> struct Node *T2 = x->right;
// Create Node
struct Node { x->right = y;
int key; y->left = T2;
struct Node *left;
struct Node *right; y->height = max(height(y->left), height(y->right)) + 1;
int height; x->height = max(height(x->left), height(x->right)) + 1;
}; return x;
int max(int a, int b); }
// Calculate height // Left rotate
int height(struct Node *N) { struct Node *leftRotate(struct Node *x) {
if (N == NULL) struct Node *y = x->right;
return 0; struct Node *T2 = y->left;
return N->height;
} y->left = x;
x->right = T2;
int max(int a, int b) { x->height = max(height(x->left), height(x->right)) + 1;
return (a > b) ? a : b; y->height = max(height(y->left), height(y->right)) + 1;
}
// Create a node return y;
struct Node *newNode(int key) { }
struct Node *node = (struct Node *) // Get the balance factor
malloc(sizeof(struct Node)); int getBalance(struct Node *N) {
node->key = key; if (N == NULL)
node->left = NULL; return 0;
node->right = NULL; return height(N->left) - height(N->right);
node->height = 1; }
return (node);
}
// Insert node struct Node *minValueNode(struct Node *node) {
struct Node *insertNode(struct Node *node, int key) { struct Node *current = node;
// Find the correct position to insertNode the node and
insertNode it while (current->left != NULL)
if (node == NULL) current = current->left;
return (newNode(key));
return current;
if (key < node->key) }
node->left = insertNode(node->left, key);
else if (key > node->key) // Print the tree
node->right = insertNode(node->right, key); void printPreOrder(struct Node *root) {
else if (root != NULL) {
return node; printf("%d ", root->key);
// Update the balance factor of each node and printPreOrder(root->left);
// Balance the tree printPreOrder(root->right);
node->height = 1 + max(height(node->left), }
height(node->right)); }
int balance = getBalance(node); int main() {
if (balance > 1 && key < node->left->key) struct Node *root = NULL;
return rightRotate(node);
if (balance < -1 && key > node->right->key) root = insertNode(root, 2);
return leftRotate(node); root = insertNode(root, 1);
if (balance > 1 && key > node->left->key) { root = insertNode(root, 7);
node->left = leftRotate(node->left); root = insertNode(root, 4);
return rightRotate(node); root = insertNode(root, 5);
} root = insertNode(root, 3);
if (balance < -1 && key < node->right->key) { root = insertNode(root, 8);
node->right = rightRotate(node->right);
return leftRotate(node); printPreOrder(root);
} return 0;
return node; }
}
// Delete a nodes if (root == NULL)
struct Node *deleteNode(struct Node *root, int key) { return root;
// Find the node and delete it // Update the balance factor of each node and
if (root == NULL) // balance the tree
return root; root->height = 1 + max(height(root->left),
height(root->right));
if (key < root->key)
int balance = getBalance(root);
root->left = deleteNode(root->left, key); if (balance > 1 && getBalance(root->left) >= 0)
return rightRotate(root);
else if (key > root->key)
root->right = deleteNode(root->right, key); if (balance > 1 && getBalance(root->left) < 0) {
root->left = leftRotate(root->left);
return rightRotate(root);
else { }
if ((root->left == NULL) || (root->right == NULL)) {
struct Node *temp = root->left ? root->left : root->right; if (balance < -1 && getBalance(root->right) <= 0)
return leftRotate(root);
if (temp == NULL) {
if (balance < -1 && getBalance(root->right) > 0) {
temp = root; root->right = rightRotate(root->right);
root = NULL; return leftRotate(root);
} else }
*root = *temp;
free(temp); return root;
}
} else {
struct Node *temp = minValueNode(root->right); int main() {
struct Node *root = NULL;
root->key = temp->key;
root = insertNode(root, 2);
root = insertNode(root, 1);
root->right = deleteNode(root->right, temp->key); root = insertNode(root, 7);
} root = insertNode(root, 4);
} root = insertNode(root, 5);
root = insertNode(root, 3);
root = insertNode(root, 8);
printPreOrder(root);
root = deleteNode(root, 3);
printf("\nAfter deletion: ");
printPreOrder(root);
return 0;
}
Questions