0% found this document useful (0 votes)
77 views51 pages

AVL Trees

An AVL tree is a self-balancing binary search tree where the heights of the two child subtrees of any node differ by at most one. This balances the tree during insertion and deletion operations and allows it to perform searches, insertions, and deletions in O(log n) time. The document discusses the balance property of AVL trees, the different violation cases that can occur during insertion, and how to restore balance through single and double rotations.

Uploaded by

Saleem Ashraf
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)
77 views51 pages

AVL Trees

An AVL tree is a self-balancing binary search tree where the heights of the two child subtrees of any node differ by at most one. This balances the tree during insertion and deletion operations and allows it to perform searches, insertions, and deletions in O(log n) time. The document discusses the balance property of AVL trees, the different violation cases that can occur during insertion, and how to restore balance through single and double rotations.

Uploaded by

Saleem Ashraf
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/ 51

AVL Trees

AVL Trees
 Binary search trees with a large height/depth are inefficient.

4 6

3 7

2 8

1 9

 An AVL (Adelson-Velskii and Landis) tree is a binary search tree with a


balance condition.
 The balance condition must be easy to maintain, and it ensures that the
depth of the tree is O(log n).
 An AVL tree is identical to a binary search tree, except that for every node
in the tree, the height of the left and right subtrees can differ by at most 1.
 The height of an empty tree is defined to be -1.
 The height of the left subtree minus the height of the right subtree of a node
is called the balance of the node.
 For an AVL tree, the balances of the nodes are always -1, 0 or 1.
AVL - Trees
7
5
2 8
2 8

7 1 4
1 4

3 5
3

An AVL Tree Not an AVL Tree


AVL Trees
5
2 8

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

 After an insertion, only nodes that are on


the path from the insertion point to the root
might have their balance altered
 Follow the path up to the root, find the first
node (i.e., deepest) whose new balance
violates the AVL condition.
 Call this node α
 Rebalance the tree at node α
 This guarantees that the entire tree is
balanced.
AVL Trees
 Violation may occur when an insertion into
1. left subtree of left child of α (LL case)
2. right subtree of left child of α (LR case)
3. left subtree of right child of α (RL case)
4. right subtree of right child of α (RR
case)
AVL Trees
 Violation may occur when an insertion into
1. left subtree of left child of α (LL case)
α

4. right subtree of right child of α (RR case)


α

X
AVL Trees
 Violation may occur when an insertion into
2. right subtree of left child of α (LR case)
α

3. left subtree of right child of a α (RL 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

Single Rotation for case 4


k1 k1

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)

Step1: Rotate k1 and k2


Step2: Rotate k2 and k3
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

Step1: Rotate k1 and k2


AVL Trees: Double Rotation
 Double rotation is used
 Step 1: Single Rotation
 k1 and k2 rotated
 case 2 (LR case)

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)

Step1: Rotate k2 and k3


Step2: Rotate k1 and k2
AVL Trees: Double Rotation
 Example:
AVL Trees: Double Rotation
16 15
4 4

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

Step1: Rotate k2 and k3


Step2: Rotate k1 and k2
AVL Trees: Double Rotation
 Insert 13 (This is single rotation: RR Case)
AVL Trees: Double Rotation
 Insert 12
AVL Trees: Double Rotation
 Insert 11 and 10 (single rotation), then 8
AVL Trees: Double Rotation
 Inserting 9
AVL Trees: Declaration
struct avl_node
{
element_type element;
avl_node *left;
avl_node * right;
int height;
};
avl_node * SEARCH_TREE;
AVL Trees: Height Calculation
int height(avl_node * p )
{
if( p == NULL )
return -1;
else
return p->height;
}
Insert operation for binary search
trees
tree_node* insert( int x, tree_node* T ) {
/*1*/ if( T == NULL ) { /* Create and return a one-node tree */
/*2*/ T = (SEARCH_TREE) malloc ( sizeof (struct tree_node) );
/*3*/ if( T == NULL )
/*4*/ printf("Out of space!!!");
else {
/*5*/ T->element = x;
/*6*/ T->left = T->right = NULL;
}
}
/*7*/ else if( x < T->element )
/*8*/ T->left = insert( x, T->left );
/*9*/ else if( x > T->element )
/*10*/ T->right = insert( x, T->right );
/* else x is in the tree already. We'll do nothing */
/*11*/ return T; /* Don't forget this line!! */
}
AVL Trees: Insert Operation
avl_node * insert( int x, avl_node * T) { else if( x > T->element ) {
if( T == NULL ) { /* Create and return a one-node tree */ T->right = insert( x, T->right);
T = (avl_node *) malloc ( sizeof (struct avl_node) );
if( ( height( T->right ) - height( T->left ) ) == 2
if( T == NULL )
if( x > T->right->element )
printf("Out of space!!!");
else { T = SingleRotateWithRight( T );
T->element = x; T->height = 0; else
T->left = T->right = NULL; T = DoubleRotateWithRight( T );
} }
}
/* Else x is in the tree already. We'll do nothing */
else if( x < T->element ) {
T->height = max( height(T->left), height(T->right) ) +
T->left = insert( x, T->left);
1;
if( ( height( T->left ) - height( T->right ) ) == 2
return T;
if( x < T->left->element )
T = SingleRotateWithLeft( T ); }
else
T = DoubleRotateWithLeft( T );
}
AVL Trees: Inserting 16
SEARCH_TREE = insert( 16, SEARCH_TREE)
16
avl_node*insert( int x, avl_node*T){
4 if( T == NULL ){

}
6 else if( x < T->element ) {
2
}

1 3 5 7 else if( x > T->element ) {


T->right = insert( x, T->right);

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
}

1 3 5 7 else if( x > T->element ) {


T->right = insert( x, T->right);

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);

6 avl_node*insert( int x, avl_node*T){


2 if( T == NULL ){
T = (avl_node *) malloc ( sizeof (struct avl_node) );
if( T == NULL )
1 3 5 7 printf("Out of space!!!");
else {
T->element = x; T->height = 0;
T->left = T->right = NULL;
16 }


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);
}

2 6 avl_node*insert( int x, avl_node*T){





1 3 5 7 return T;

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}

• Now the subtree writh root 7 is ubalanced


15
 perform double rotation with right
AVL Trees: SingleRotateWithLeft
/* This function can be called only if k2 has a left child. */
/* Perform a rotate between a node (k2) and its left child. */
/* Update heights. */
/* Then return new root. */
avl_node * SingleRotateWithLeft( avl_node * k2 ) {
avl_node * k1;
k1 = k2->left;
k2->left = k1->right;
k1->right = k2;
k2->height = max( height(k2->left), height(k2->right) ) + 1;
k1->height = max( height(k1->left), k2->height ) + 1;
return k1; /* New root */
}

Single Rotation for case 1


k2 k1
k2->left
k1 k2
k1->right Z k2->left
X
Y Z
Y
X
AVL Trees: SingleRotateWithRight
/* This function can be called only if k1 has a right child. */
/* Perform a rotate between a node (k1) and its right child. */
/* Update heights. */
/* Then return new root. */
avl_node * SingleRotateWithRight( avl_node * k1 ) {
avl_node * k2;
k2 = k1->right;
k1->right = k2->left ;
k2->left = k1;
k1->height = max( height(k1->left), height(k1->right) ) + 1;
k2->height = max( k1->height, height(k2->right) ) + 1;
return k2; /* New root */
}
Single Rotation for case 4
k1
k1->right k2
k2 k1
X
k2->left k1->right
Y Z
X Y
Z
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 );

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 ) );
}

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy