AVL Trees
AVL Trees
AVL Trees
Binary search trees with a large height/depth are inefficient.
4 6
3 7
2 8
1 9
7 1 4
1 4
3 5
3
7
1 4
6
3
When we do an insertion, we need to update all the balancing
information for the nodes on the path back to the root
but the reason that insertion is potentially difficult is that inserting a
node could violate the AVL tree property.
For instance, inserting 6 into the AVL tree in figure would destroy
the balance condition at the node with key 8.
If this is the case, then the property has to be restored before the
insertion step is considered over.
It turns out that this can always be done with a simple modification to
the tree, known as a rotation.
AVL Trees
After the insertion/rotation operations, the
following properties of the AVL tree must
be restored
(a) the inorder traversal of the transformed
tree is the same as for the original tree (i.e.,
the new tree remains a binary search tree)
(b) the tree after the insertion/rotation is
height balanced.
AVL Trees
X
AVL Trees
Violation may occur when an insertion into
2. right subtree of left child of α (LR case)
α
X
X
AVL Trees
Rotation
to restore the AVL tree after
insertion
Single rotation
for case 1 and 4
Double rotation
for case 2 and 3
AVL Trees
Single Rotation for case 1
k2 k2
k1 kk11
Z Z
k2
Y Y
X X
Y Z
k2 k22
X X
k1
Y Y
Z Z
X Y
AVL Trees: Single Rotation
Example: 3 2 1 4 5 6 7
construct AVL Tree
321
3
3
2
2
1
1
AVL Trees: Single Rotation
Example: 3 2 1 4 5 6 7
construct AVL Tree
321
3
2
2
1 3
1
AVL Trees: Single Rotation
45
2
2
1 4
1 3
3 5
4
5
AVL Trees: Single Rotation
6
1 4 2
5 1 4
3
3 5
6
6
AVL Trees: Single Rotation
7
4
2 5
2 5
1 3 6
1 3 6
7
7
AVL Trees: Double Rotation
Single rotation fails to fix cases 2 and 3
i.e. LR and RL cases
AVL Trees: Double Rotation
Double rotation is used
case 2 (LR case)
k3 k3
k1 k1
k2 D k2 D
A A
B C B C
k3
k3
k1 k2
k2 D
k1 D
A C
B C
A B
LR LL
Step1: Rotate k1 and k2
AVL Trees: Double Rotation
Double rotation is used
Step 2: Single Rotation
k3 and k2 rotated
case 2 (LR case)
k3 k2
k1
k1 k3
k2 D
A
C A B C D
B
LR Balanced
Step2: Rotate k2 and k3
AVL Trees: Double Rotation
case 3 (RL case)
2 6 6
2
1 3 5 7 k1 k1
1 3 5 7
16 k3 16 k3
15 Double Rotation 15 k2
k2
Step 1: Rotate 15 and 16
AVL Trees: Double Rotation
16 15
4 4
2 6 6
2
1 3 5 7 k1 k1
1 3 5 7
16 k3 15 k2
15 Double Rotation k3 16
k2
Step 2: Rotate 7 and 15
AVL Trees: Double Rotation
Insert 14
}
6 else if( x < T->element ) {
2
}
NULL
AVL Trees: Inserting 16
SEARCH_TREE = insert( 16, SEARCH_TREE)
16
4
2 6
else if( x > T->element ) {
T->right = insert( x, T->right);
1 3 5 7
avl_node*insert( int x, avl_node*T){
if( T == NULL ){
T = (avl_node *) malloc ( sizeof (struct avl_node) );
16
NULL if( T == NULL )
printf("Out of space!!!");
else {
T->element = x; T->height = 0;
T->left = T->right = NULL;
}
Recursion rolls back
AVL Trees: Inserting 16
SEARCH_TREE = insert( 16, SEARCH_TREE)
16
else if( x > T->element ) {
4
T->right = insert( x, T->right);
if( ( height( T->left ) - height( T->right ) ) == 2
{ /*condition is false here */
2 6
}
}
T->height = max( height(T->left), height(T->right) ) + 1;
1 3 5 7 return T;
}
16
AVL Trees: Inserting 15
SEARCH_TREE = insert( 15, SEARCH_TREE)
15
avl_node*insert( int x, avl_node*T){
4 if( T == NULL ){
}
6 else if( x < T->element ) {
2
}
16
else if( x < T->element ) {
T->left = insert( x, T->left);
NULL
AVL Trees: Inserting 15
SEARCH_TREE = insert( 16, SEARCH_TREE)
15
4 else if( x < T->element ) {
T->reft = insert( x, T->left);
…
15
NULL …
…
return T; Recursion rolls back
AVL Trees: Inserting 15
SEARCH_TREE = insert( 16, SEARCH_TREE)
15
4 else if( x > T->element ) {
T->right = insert( x, T->right);
}
16
15
Recursion rolls back further
AVL Trees: Inserting 15
SEARCH_TREE = insert( 16, SEARCH_TREE)
15
4 else if( x > T->element ) {
T->right = insert( x, T->right);
if( ( height( T->right ) - height( T->left ) ) == 2
if( x > T->right->element )
2 6 T = SingleRotateWithRight( T );
else
T = DoubleRotateWithRight( T );
}
1 3 5 7 /* Else x is in the tree already. We'll do nothing */
T->height = max( height(T->left), height(T->right) ) + 1;
return T;
16}
k3
k3
k1 k2
k2 D
k1 D
A C
B C
A B
AVL Trees: DoubleRotateWithLeft
/* This function can be called only if k3 has a left child */
/* and k3's left child has a right child */
/* Do the left-right double rotation. Update heights */
avl_node * DoubleRotateWithLeft( avl_node * k3 )
{
/* rotate between k1 and k2 */
k3->left = SingleRotateWithRight( k3->left );
/* rotate between k3 and k2 */
return(SingleRotateWithLeft( k3 ) );
}
k3
k3
k1 k2
k2 D
k1 D
A C
B C
A B
AVL Trees: DoubleRotateWithLeft
/* This function can be called only if k3 has a left child */
/* and k3's left child has a right child */
/* Do the left-right double rotation. Update heights */
avl_node * DoubleRotateWithLeft( avl_node * k3 )
{
/* rotate between k1 and k2 */
k3->left = SingleRotateWithRight( k3->left );
/* rotate between k3 and k2 */
return(SingleRotateWithLeft( k3 ) );
}
k3 k2
k1
k1 k3
k2 D
A
C A B C D
B
AVL Trees: DoubleRotateWithLeft
/* This function can be called only if k3 has a left child */
/* and k3's left child has a right child */
/* Do the left-right double rotation. Update heights */
avl_node * DoubleRotateWithLeft( avl_node * k3 )
{
/* rotate between k1 and k2 */
k1 = k3->left;
k2 = SingleRotateWithRight( k1);
k3->left = k2
}
k3
k3
k1 k2
k2 D
k1 D
A C
B C
A B
AVL Trees: DoubleRotateWithLeft
/* This function can be called only if k3 has a left child */
/* and k3's left child has a right child */
/* Do the left-right double rotation. Update heights */
avl_node * DoubleRotateWithLeft( avl_node * k3 )
{
/* rotate between k1 and k2 */
k1 = k3->left;
k2 = SingleRotateWithRight( k1);
k3->left = k2
/* rotate between k3 and k2 */
k2 =SingleRotateWithLeft( k3 )
return(k2);
} k 3
k3
k1 k2
k2 D
k1 D
A C
B C
A B
AVL Trees: DoubleRotateWithLeft
/* This function can be called only if k3 has a left child */
/* and k3's left child has a right child */
/* Do the left-right double rotation. Update heights */
avl_node * DoubleRotateWithLeft( avl_node * k3 )
{
/* rotate between k1 and k2 */
k1 = k3->left;
k2 = SingleRotateWithRight( k1);
k3->left = k2
/* rotate between k3 and k2 */
k2 =SingleRotateWithLeft( k3 )
return(k2);
} k 3 k2
k1 k1 k3
k2 D
A A B C D
B C
AVL Trees: Double Rotation
4 4
2 6 2 6
1 3 5 7 k1 k1
1 3 5 7
16 k3 16 k3
15
k2 Double Rotation 15 k
2
Step 1: Rotate 15 and 16
avl_node * DoubleRotateWithRight( avl_node * k1 )
{
/* rotate between k3 (16) and k2 (15 )*/
k1->right = SingleRotateWithLeft( k1->right );
/* rotate between k1 (7) and k2 (15) */
return(SingleRotateWithRight( k1 ) );
}
AVL Trees: Double Rotation
4 4
2 6 2 6
1 3 5 7 k1 k1
1 3 5 7
16 k3 15 k2
15
k2 Double Rotation k3 16
Step 2: Rotate 7 and 15
avl_node * DoubleRotateWithRight( avl_node * k1 )
{
/* rotate between k3 (16) and k2 (15 )*/
k1->right = SingleRotateWithLeft( k1->right );
/* rotate between k1 (7) and k2 (15) */
return(SingleRotateWithRight( k1 ) );
}