0% found this document useful (0 votes)
46 views21 pages

AVL Search Tree

This C code implements an AVL tree data structure. It includes functions to insert nodes, rotate the tree for balance, calculate heights and balance factors, and print the tree. The insert function recursively finds the correct position, inserts the node, updates heights and balances the tree by rotating if needed. Rotations are done by leftRotate and rightRotate functions. The overall time complexity of insert is O(log n) due to the self-balancing nature of the AVL tree.

Uploaded by

Amar Thakur
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
46 views21 pages

AVL Search Tree

This C code implements an AVL tree data structure. It includes functions to insert nodes, rotate the tree for balance, calculate heights and balance factors, and print the tree. The insert function recursively finds the correct position, inserts the node, updates heights and balances the tree by rotating if needed. Rotations are done by leftRotate and rightRotate functions. The overall time complexity of insert is O(log n) due to the self-balancing nature of the AVL tree.

Uploaded by

Amar Thakur
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 21

Lovely Professional University, Punjab

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.

An example of an AVL tree where


the heights are shown next to the
nodes:
4
• AVL tree is a binary search tree with balance
condition
– To ensure depth of the tree is O(log(N))
– And consequently, search/insert/remove
complexity bound O(log(N))
• Balance condition
– For every node in the tree, height of left and right
subtree 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

• Violation cases at node k (deepest node)


1. An insertion into left subtree of left child of k
2. An insertion into right subtree of left child of k
3. An insertion into left subtree of right child of k
4. An insertion into right subtree of right child of k

– Cases 1 and 4 equivalent


• Single rotation to rebalance
– Cases 2 and 3 equivalent
• Double rotation to rebalance
7
AVL Trees Complexity
• Overhead
– Extra space for maintaining height information at each
node
– Insertion and deletion become more complicated, but still
O(log N)
• Advantage
– Worst case O(log(N)) for insert, delete, and search

8
Single Rotation (Case 1)

• Replace node k2 by node k1


• Set node k2 to be right child of node k1
• Set subtree Y to be left child of node k 2
• Case 4 is similar

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

• Continuing the previous example by inserting


– 16 down to 10, and then 8 and 9

• Inserting 16 and 15
4
4
2 6
2 6
1 3 5 15
1 3 5 7
7 16
16
15

14
Blank

• Best case time complexity of traverse


operation in AVL tree.
• A. O(1)
• B. O(log n)
• C. O(n)
• D. None of these

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

• Worst case time complexity of insertin of


element in AVL tree.
• A. O(1)
• B. O(log n)
• C. O(n)
• D. None of these

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

You might also like