Download as ppt, pdf, or txt
Download as ppt, pdf, or txt
You are on page 1of 177

Tree Data Structures

 There are a number of applications where linear data structures are


not appropriate.
 Consider a genealogy tree of a family.

Mohammad Aslam Khan

Sohail Aslam Javed Aslam Yasmeen Aslam

Haaris Saad Qasim Asim Fahd Ahmad Sara Omer


Tree Data Structure
 A linear linked list will not be able to capture the tree-like
relationship with ease.
 Shortly, we will see that for applications that require searching,
linear data structures are not suitable.
 We will focus our attention on binary trees.
Binary Tree
A binary tree is a finite set of elements that is
either empty or is partitioned into three disjoint
subsets.
 The first subset contains a single element called
the root of the tree.
 The other two subsets are themselves binary
trees called the left and right subtrees.
 Each element of a binary tree is called a node of
the tree.
Binary Tree
 Binary tree with 9 nodes.

B C

D E F

G H I
Binary Tree
root

B C

D E F

G H I

Left subtree Right subtree


Binary Tree
 Recursive definition

A
root

B C

D E F

Left subtree G H I

Right subtree
Binary Tree
 Recursive definition

B C
root

D E F

G H I

Left subtree
Binary Tree
 Recursive definition

B C

D E F

root
G H I
Binary Tree
 Recursive definition

A
root

B C

D E F

G H I

Right subtree
Binary Tree
 Recursive definition

B C
root

D E F

G H I

Left subtree Right subtree


Not a Tree
 Structures that are not trees.

B C

D E F

G H I
Not a Tree
 Structures that are not trees.

B C

D E F

G H I
Not a Tree
 Structures that are not trees.

B C

D E F

G H I
Binary Tree: Terminology

parent
A

Left descendant B C Right descendant

D E F

G H I

Leaf nodes Leaf nodes


Binary Tree
 If every non-leaf node in a binary tree has non-empty left and right
subtrees, the tree is termed a strictly binary tree.

B C

D E J F

G K H I
Level of a Binary Tree Node
 The level of a node in a binary tree is defined as follows:
 Root has level 0,
 Level of any other node is one more than the level its parent (father).
 The depth of a binary tree is the maximum level of any leaf in the
tree.
Level of a Binary Tree Node

A 0 Level 0

B 1 C 1 Level 1

D 2 E 2 F 2 Level 2

G 3 H 3 I 3 Level 3
Complete Binary Tree
A complete binary tree of depth d is the strictly
binary all of whose leaves are at level d.
0
A

B 1 C 1

D 2 E 2 F 2 G 2

H 3 I J 3 K L 3 M 3 N 3 O 3
Complete Binary Tree

A Level 0: 20 nodes

B C Level 1: 21 nodes

D E F G Level 2: 22 nodes

H I J K L Level 3: 23 nodes
Complete Binary Tree
 At level k, there are 2k nodes.
 Total number of nodes in the tree of depth d:

20+ 21+ 22 + ………. + 2d = 2d+1 – 1

 In a complete binary tree, there are 2d leaf nodes and (2d - 1) non-
leaf (inner) nodes.
j=0
d
Complete Binary Tree
 If the tree is built out of ‘n’ nodes then

n = 2d+1 – 1
or log2(n+1) = d+1
or d = log2(n+1) – 1
 I.e., the depth of the complete binary tree built
using ‘n’ nodes will be log2(n+1) – 1.
 For example, for n=1,000,000, log2(1000001) is
less than 20; the tree would be 20 levels deep.
 The significance of this shallowness will become
evident later.
Operations on Binary Tree
 There are a number of operations that can be defined for a binary
tree.
 If p is pointing to a node in an existing tree then
 left(p) returns pointer to the left subtree
 right(p) returns pointer to right subtree
 parent(p) returns the father of p
 brother(p) returns brother of p.
 info(p) returns content of the node.
Operations on Binary Tree
 In order to construct a binary tree, the following can be useful:
 setLeft(p,x) creates the left child node of p. The child node contains
the info ‘x’.
 setRight(p,x) creates the right child node of p. The child node
contains the info ‘x’.
Applications of Binary Trees
 A binary tree is a useful data structure when two-way decisions
must be made at each point in a process.
 For example, suppose we wanted to find all duplicates in a list of
numbers:

14, 15, 4, 9, 7, 18, 3, 5, 16, 4, 20, 17, 9, 14, 5


Applications of Binary Trees
 One way of finding duplicates is to compare each number with all
those that precede it.

14, 15, 4, 9, 7, 18, 3, 5, 16, 4, 20, 17, 9, 14, 5

14, 15, 4, 9, 7, 18, 3, 5, 16, 4, 20, 17, 9, 14, 5


Searching for Duplicates
 If the list of numbers is large and is growing, this procedure involves
a large number of comparisons.
 A linked list could handle the growth but the comparisons would still
be large.
 The number of comparisons can be drastically reduced by using a
binary tree.
 The tree grows dynamically like the linked list.
Searching for Duplicates
 The binary tree is built in a special way.
 The first number in the list is placed in a node that is designated as
the root of a binary tree.
 Initially, both left and right subtrees of the root are empty.
 We take the next number and compare it with the number placed in
the root.
 If it is the same then we have a duplicate.
Searching for Duplicates
 Otherwise, we create a new tree node and put the new number in it.
 The new node is made the left child of the root node if the second
number is less than the one in the root.
 The new node is made the right child if the number is greater than
the one in the root.
A

B C
Searching for Duplicates

14

14, 15, 4, 9, 7, 18, 3, 5, 16, 4, 20, 17, 9, 14, 5


Searching for Duplicates

15 14

15, 4, 9, 7, 18, 3, 5, 16, 4, 20, 17, 9, 14, 5


Searching for Duplicates

14

15

15, 4, 9, 7, 18, 3, 5, 16, 4, 20, 17, 9, 14, 5


Searching for Duplicates

4 14

15

4, 9, 7, 18, 3, 5, 16, 4, 20, 17, 9, 14, 5


Searching for Duplicates

14

4 15

4, 9, 7, 18, 3, 5, 16, 4, 20, 17, 9, 14, 5


Searching for Duplicates

9 14

4 15

9, 7, 18, 3, 5, 16, 4, 20, 17, 9, 14, 5


Searching for Duplicates

14

4 15

9, 7, 18, 3, 5, 16, 4, 20, 17, 9, 14, 5


Searching for Duplicates

7 14

4 15

7, 18, 3, 5, 16, 4, 20, 17, 9, 14, 5


Searching for Duplicates

14

4 15

7, 18, 3, 5, 16, 4, 20, 17, 9, 14, 5


Searching for Duplicates

18 14

4 15

18, 3, 5, 16, 4, 20, 17, 9, 14, 5


Searching for Duplicates

14

4 15

9 18

18, 3, 5, 16, 4, 20, 17, 9, 14, 5


Searching for Duplicates

3 14

4 15

9 18

3, 5, 16, 4, 20, 17, 9, 14, 5


Searching for Duplicates

14

4 15

3 9 18

3, 5, 16, 4, 20, 17, 9, 14, 5


Searching for Duplicates

5 14

4 15

3 9 18

5, 16, 4, 20, 17, 9, 14, 5


Searching for Duplicates

14

4 15

3 9 18

5, 16, 4, 20, 17, 9, 14, 5


Searching for Duplicates

16 14

4 15

3 9 18

16, 4, 20, 17, 9, 14, 5


Searching for Duplicates

14

4 15

3 9 18

7 16

16, 4, 20, 17, 9, 14, 5


Searching for Duplicates

4 14

4 15

3 9 18

7 16

4, 20, 17, 9, 14, 5


Searching for Duplicates

20 14

4 15

3 9 18

7 16

20, 17, 9, 14, 5


Searching for Duplicates

14

4 15

3 9 18

7 16 20

20, 17, 9, 14, 5


Searching for Duplicates

17 14

4 15

3 9 18

7 16 20

17, 9, 14, 5
Searching for Duplicates

14

4 15

3 9 18

7 16 20

5 17

17, 9, 14, 5
Searching for Duplicates

14

4 15

3 9 18

7 16 20

5 17

9, 14, 5
C++ Implementation
#include <stdlib.h>
template <class Object>
class TreeNode {
public:
// constructors
TreeNode()
{
this->object = NULL;
this->left = this->right = NULL;
};
TreeNode( Object* object )
{
this->object = object;
this->left = this->right = NULL;
};
C++ Implementation
Object* getInfo()
{
return this->object;
};
void setInfo(Object* object)
{
this->object = object;
};
TreeNode* getLeft()
{
return left;
};
void setLeft(TreeNode *left)
{
this->left = left;
};
C++ Implementation
TreeNode *getRight()
{
return right;
};
void setRight(TreeNode *right)
{
this->right = right;
};

int isLeaf( )
{
if( this->left == NULL && this->right == NULL )
return 1;
return 0;
};
C++ Implementation
private:
Object* object;
TreeNode* left;
TreeNode* right;
}; // end class TreeNode
C++ Implementation
#include <iostream>
#include <stdlib.h>
#include "TreeNode.cpp"

int main(int argc, char *argv[])


{
int x[] = { 14, 15, 4, 9, 7, 18, 3, 5, 16,4, 20, 17,
9, 14,5, -1};
TreeNode<int>* root = new TreeNode<int>(&x[0]);
//root->setInfo( &x[0] );
for(int i=1; x[i] > 0; i++ )
{
insert(root, &x[i] );
}
}
C++ Implementation
void insert(TreeNode<int>* root, int* info)
{
TreeNode<int>* node = new TreeNode<int>(info);
TreeNode<int> *p, *q;
p = q = root;
while( *info != *(p->getInfo()) && q != NULL )
{
p = q;
if( *info < *(p->getInfo()) )
q = p->getLeft();
else
q = p->getRight();
}
C++ Implementation
if( *info == *(p->getInfo()) ){
cout << "attempt to insert duplicate: "
<< *info << endl;
delete node;
}
else if( *info < *(p->getInfo()) )
p->setLeft( node );
else
p->setRight( node );
} // end of insert
Trace of insert
p
17 q 14

4 15

3 9 18

7 16 20

17, 9, 14, 5
Trace of insert
p
17 14

4 q 15

3 9 18

7 16 20

17, 9, 14, 5
Trace of insert

17 14

4 p 15
q
3 9 18

7 16 20

17, 9, 14, 5
Trace of insert

17 14

4 p 15

3 9 q 18

7 16 20

17, 9, 14, 5
Trace of insert

17 14

4 15

3 9 p 18
q
7 16 20

17, 9, 14, 5
Trace of insert

17 14

4 15

3 9 p 18

7 q 16 20

17, 9, 14, 5
Trace of insert

17 14

4 15

3 9 18

7 p 16 20
q
5

17, 9, 14, 5
Trace of insert

17 14

4 15

3 9 18

7 p 16 20

5 q

17, 9, 14, 5
Trace of insert

14

4 15

3 9 18

7 p 16 20

5 node 17

17, 9, 14, 5 p->setRight( node );


C++ Implementation
void search(TreeNode<int>* root, int * info)
{
TreeNode<int> *p;
p = root;
while( *info != *(p->getInfo()) && p != NULL )
{

if( *info < *(p->getInfo()) )


p = p->getLeft();
else
p = p->getRight();
}
C++ Implementation
if( *info == *(p->getInfo()) ){
cout << “node found"
<< *info << endl;
}
else
cout<< “node not found”;
} // end of search
Trace of insert
p
16 14

4 15

3 9 18

7 16 20

17, 9, 14, 5
Trace of insert

16 14

4 p 15

3 9 18

7 16 20

17, 9, 14, 5
Trace of insert

16 14

4 15

3 9 p 18

7 16 20

17, 9, 14, 5
Trace of insert

16 14

4 15

3 9 18

7 p 16 20

17, 9, 14, 5
Cost of Search
 Given that a binary tree is level d deep. How long does it take to find
out whether a number is already present?
 Consider the insert(17) in the example tree.
 Each time around the while loop, we did one comparison.
 After the comparison, we moved a level down.
Cost of Search
 With the binary tree in place, we can write a routine find(x) that
returns true if the number x is present in the tree, false otherwise.
 How many comparison are needed to find out if x is present in the
tree?
 We do one comparison at each level of the tree until either x is
found or q becomes NULL.
Cost of Search
 If the binary tree is built out of n numbers, how many comparisons
are needed to find out if a number x is in the tree?
 Recall that the depth of the complete binary tree built using ‘n’
nodes will be log2(n+1) – 1.
 For example, for n=100,000, log2(100001) is less than 20; the tree
would be 20 levels deep.
Cost of Search
 If the tree is complete binary or nearly complete, searching through
100,000 numbers will require a maximum of 20 comparisons.
 Or in general, approximately log2(n).
 Compare this with a linked list of 100,000 numbers. The
comparisons required could be a maximum of n.
Binary Search Tree
 A binary tree with the property that items in the left subtree are
smaller than the root and items are larger or equal in the right
subtree is called a binary search tree (BST).
 The tree we built for searching for duplicate numbers was a binary
search tree.
 BST and its variations play an important role in searching
algorithms.
Traversing a Binary Tree
 Suppose we have a binary tree, ordered (BST) or unordered.
 We want to print all the values stored in the nodes of the tree.
 In what order should we print them?
Traversing a Binary Tree
 Ways to print a 3 node tree:

14

4 15

(4, 14, 15), (4,15,14)


(14,4,15), (14,15,4)
(15,4,14), (15,14,4)
Traversing a Binary Tree
 In case of the general binary tree:

N node

L left right R
subtree subtree

(L,N,R), (L,R,N)
(N,L,R), (N,R,L)
(R,L,N), (R,N,L)
Traversing a Binary Tree
 Three common ways

N node

left right
L subtree subtree R

Preorder: (N,L,R)
Inorder: (L,N,R)
Postorder: (L,R,N)
Traversing a Binary Tree
void preorder(TreeNode<int>* treeNode)
{
if( treeNode != NULL )
{
cout << *(treeNode->getInfo())<<" ";
preorder(treeNode->getLeft());
preorder(treeNode->getRight());
}
}
Traversing a Binary Tree
void inorder(TreeNode<int>* treeNode)
{
if( treeNode != NULL )
{
inorder(treeNode->getLeft());
cout << *(treeNode->getInfo())<<" ";
inorder(treeNode->getRight());
}
}
Traversing a Binary Tree
void postorder(TreeNode<int>* treeNode)
{
if( treeNode != NULL )
{
postorder(treeNode->getLeft());
postorder(treeNode->getRight());
cout << *(treeNode->getInfo())<<" ";
}
}
Traversing a Binary Tree
cout << "inorder: "; preorder( root);
cout << "inorder: "; inorder( root );
cout << "postorder: "; postorder( root );
Traversing a Binary Tree
14

4 15

3 9 18

7 16 20

5 17

Preorder: 14 4 3 9 7 5 15 18 16 17 20
Traversing a Binary Tree
14

4 15

3 9 18

7 16 20

5 17

Inorder: 3 4 5 7 9 14 15 16 17 18 20
Traversing a Binary Tree
14

4 15

3 9 18

7 16 20

5 17

Postorder: 3 5 7 9 4 17 16 20 18 15 14
Traversing a Binary Tree
12

8 15

3 14 18
9

2 10 20
17

11

Postorder: 3 5 7 9 4 17 16 20 18 15 14
Recursive Call
 Recall that a stack is used during function calls.
 The caller function places the arguments on the stack and passes
control to the called function.
 Local variables are allocated storage on the call stack.
 Calling a function itself makes no difference as far as the call stack
is concerned.
Stack Layout during a call
 Here is stack layout when function F calls function F (recursively):

Parameters(F) Parameters(F) Parameters(F)


Local variables(F) Local variables(F) Local variables(F)

Return address(F) Return address(F) Return address(F)


sp
Parameters(F) Parameters(F)
sp
Local variables(F)

Return address(F)
sp
At point of call During execution of F After call
Recursion: preorder
14 preorder(14)
14
..preorder(4)
4 15 4
....preorder(3)
3
......preorder(null)
3 9 18 ......preorder(null)
....preorder(9)
9
7 16 20
......preorder(7)
7
........preorder(5)
5 17
5
..........preorder(null)
..........preorder(null)
........preorder(null)
......preorder(null)
Recursion: preorder
14 ..preorder(15)
15
....preorder(null)
4 15 ....preorder(18)
18
......preorder(16)
3 9 18 16
........preorder(null)
7 16 20 ........preorder(17)
17
..........preorder(null)
5 17 ..........preorder(null)
......preorder(20)
20
........preorder(null)
........preorder(null)
Recursion: inorder
14 inorder(14)
..inorder(4)
....inorder(3)
4 15 ......inorder(null)
3
......inorder(null)
4
3 9 18 ....inorder(9)
......inorder(7)
........inorder(5)
7 16 20
..........inorder(null)
5
..........inorder(null)
5 17
7
........inorder(null)
9
......inorder(null)
14
Recursion: inorder
14 ..inorder(15)
....inorder(null)
15
4 15 ....inorder(18)
......inorder(16)
........inorder(null)
3 9 18 16
........inorder(17)
7 16 20 ..........inorder(null)
17
..........inorder(null)
5 17 18
......inorder(20)
........inorder(null)
20
........inorder(null)
Level-order Traversal
 There is yet another way of traversing a binary tree that is not
related to recursive traversal procedures discussed previously.
 In level-order traversal, we visit the nodes at each level before
proceeding to the next level.
 At each level, we visit the nodes in a left-to-right order.
Level-order Traversal
14

4 15

3 9 18

7 16 20

5 17

Level-order: 14 4 15 3 9 18 7 16 20 5 17
Deleting a node in BST
 As is common with many data structures, the hardest operation is
deletion.
 Once we have found the node to be deleted, we need to consider
several possibilities.
 If the node is a leaf, it can be deleted immediately.
Deleting a node in BST
 Ifthe node has one child, the node can be
deleted after its parent adjusts a pointer to
bypass the node and connect to inorder
successor.
6

2 8

1 4

3
Deleting a node in BST
 The inorder traversal order has to be maintained after the delete.

6  6

2 8 2 8

1 4 1 4

3 3
Deleting a node in BST
 The inorder traversal order has to be maintained after the delete.

6  6  6

2 8 2 8 2 8

1 4 1 4 1 3

3 3
Deleting a node in BST
 The complicated case is when the node to be deleted has both left
and right subtrees.
 The strategy is to replace the data of this node with the smallest
data of the right subtree and recursively delete that node.
Deleting a node in BST
Delete(2): locate inorder successor

2 8

1 5

4
Inorder
successor
Deleting a node in BST
Delete(2): locate inorder successor

6  Inorder successor will be the left-most


node in the right subtree of 2.
2 8
 The inorder successor will not have a left
child because if it did, that child would be
1 5 the left-most node.

4
Inorder
successor
Deleting a node in BST
Delete(2): copy data from inorder successor

6  6

2 8 3 8

1 5 1 5

3 3

4 4
Deleting a node in BST
Delete(2): remove the inorder successor

6  6  6

2 8 3 8 3 8

1 5 1 5 1 5

3 3 3

4 4 4
Deleting a node in BST
Delete(2)
 6  6

3 8 3 8

1 5 1 5

3 4

4
Deletion
12

3 15

2 14 18
10

9 20
17

11
AVL Tree

 AVL (Adelson-Velskii and Landis) tree.


 An AVL tree is identical to a BST except
 height of the left and right subtrees can differ by at most 1.
 height of an empty tree is defined to be (–1).
AVL Tree

 An AVL Tree
height
5

2 8

1 4 7

3
AVL Tree

 Not an AVL tree


height
6 3

2 8 2

1 4 1

3 5 0
Balanced Binary Tree

 The height of a binary tree is the maximum level of its leaves


 The balance of a node in a binary tree is defined as the height of its left
subtree minus height of its right subtree.
 Here, for example, is a balanced tree. Each node has an indicated balance
of 1, 0, or –1.
Balanced Binary Tree

-1

1 0

0 0 1 -1

0 0 0 0 0 0

0 0 0 0
Balanced Binary Tree
Insertions and effect on balance

-1

1 0

0 0 1 -1

0 0 B B 0 0 0 0

U1 U2 U3 U4 0 0 B B B B 0 0

U5 U6 U7 U8 U9 U10 U11 U12


Balanced Binary Tree

 Tree becomes unbalanced only if the newly inserted node

 is a left descendant of a node that previously had a balance of 1 (U1 to


U8),
 or is a descendant of a node that previously had a balance of –1 (U9 to
U12)
Balanced Binary Tree
Insertions and effect on balance

-1

1 0

0 0 1 -1

0 0 B B 0 0 0 0

U1 U2 U3 U4 0 0 B B B B 0 0

U5 U6 U7 U8 U9 U10 U11 U12


Balanced Binary Tree

Consider the case of node that was previously 1

-1

1 0

0 0 1 -1

0 0 B B 0 0 0 0

U1 U2 U3 U4 0 0 B B B B 0 0

U5 U6 U7 U8 U9 U10 U11 U12


Inserting New Node in AVL Tree

A 1

B 0

T3

T1 T2 1
Inserting New Node in AVL Tree

A 2

B 1

T3

T1 T2 1
2

new
Inserting New Node in AVL Tree

A 2 B 0

A
B 1 0
T1
T3

T1 T2 1 T2 T3
2
new

new

Inorder: T1 B T2 A T3 Inorder: T1 B T2 A T3
AVL Tree Building Example

 Let us work through an example that inserts numbers in a balanced search


tree.
 We will check the balance after each insert and rebalance if necessary
using rotations.
AVL Tree Building Example

Insert(1)

1
AVL Tree Building Example

Insert(2)

2
AVL Tree Building Example

Insert(3) single left rotation

1 -2

3
AVL Tree Building Example

Insert(3) single left rotation

1 -2

3
AVL Tree Building Example

Insert(3)

1 3
AVL Tree Building Example
12
9
Insert(3) single left rotation

1 -2

3
AVL Tree Building Example
13
0
Insert(3)

1 3
AVL Tree Building Example
13
1
Insert(4)

1 3

4
AVL Tree Building Example
13
2
Insert(5)

1 3 -2

5
AVL Tree Building Example
13
3
Insert(5)

1 4

3 5
AVL Tree Building Example
13
4
Insert(6)

2 -2

1 4

3 5

6
AVL Tree Building Example
13
5
Insert(6)

2 5

1 3 6
AVL Tree Building Example
13
6
Insert(7)

2 5 -2

1 3 6

7
AVL Tree Building Example
13
7
Insert(7)

2 6

1 3 5 7
AVL Tree Building Example
13
8

Insert(16)
4

2 6

1 3 5 7

16
AVL Tree Building Example
13
9
Insert(15)

2 6

1 3 5 7 -2

16

15
AVL Tree Building Example
14
0
Insert(15)

2 6

1 3 5 16 -2

15
Cases for Rotation
14
1
 Single rotation does not seem to restore the balance.
 The problem is the node 15 is in an inner subtree that is too deep.
 Let us revisit the rotations.
Cases for Rotation
14
2
 Let us call the node that must be rebalanced .
 Since any node has at most two children, and a height imbalance requires
that ’s two subtrees differ by two (or –2), the violation will occur in four
cases:
Cases for Rotation
14
3
1. An insertion into left subtree of the left child of .
2. An insertion into right subtree of the left child of .
3. An insertion into left subtree of the right child of .
4. An insertion into right subtree of the right child of .
Cases for Rotation
14
4
 The insertion occurs on the “outside” (i.e., left-left or right-right) in
cases 1 and 4
 Single rotation can fix the balance in cases 1 and 4.
 Insertion occurs on the “inside” in cases 2 and 3 which single rotation
cannot fix.
Cases for Rotation
14
5
 Single right rotation to fix case 1.

 k2  k1

k1 k2
Z Level n-2 X

X Y Level n-1 Y Z
new

Level n
new
Cases for Rotation
14
6
 Single left rotation to fix case 4.

k1 k2

k2 k1
X Level n-2

Z
Y Level n-1
X Y

Z
Level n
Cases for Rotation
14
7
 Single right rotation fails to fix case 2.

 k2  k1

k1 k2
Z Level n-2 X

X Y Level n-1 Y Z

Level n
new new
Cases for Rotation
14
8
Y is non-empty because the
new node was inserted in Y.
k2
 Thus Y has a root and two
k1 subtrees.
Z
 View the entire tree with four
X
subtrees connected with 3
nodes.
Y
Cases for Rotation
14
9
Y is non-empty because the
new node was inserted in Y.
k3
 Thus Y has a root and two
k1 subtrees.
D
 View the entire tree with four
k2
A
subtrees connected with 3
nodes.
B C
Cases for Rotation
15
0

k3
 Exactly one of tree B or C
is two levels deeper than
k1
D; we are not sure which
one.
k2  Good thing: it does not
D matter.
A  To rebalance, k3 cannot be
1
B C
left as the root.
2

new new’

New node inserted a either of the two

spots
Cases for Rotation
15
1

k3
 A rotation between k3
and k1 (k3 was k2 then)
k1 was shown to not work.
 The only alternative is to
k2
D
place k2 as the new root.

A
 This forces k1 to be k2‘s
B C
1
left child and k3 to be its
2 right child.
new new’

New node inserted a either of the two

spots
Cases for Rotation
15
2
 Left-right double rotation to fix case 2.

k3 k3

Rotate left
k1 k2

k2
k1 D
D
C

A
1 B
B C

2 A new’

New node inserted a either of the two


new new’ new
spots
Cases for Rotation
15
3
 Left-right double rotation to fix case 2.

k3 k2
Rotate right

k2 k1 k3

k1 D

C B C

A D
B

A new’ new new’

new
Cases for Rotation
15
4
 Right-left double rotation to fix case 3.

k1 Rotate right k1

k3 k2
A A
k2 k3
D B

B C C D
Cases for Rotation
15
5
 Right-left double rotation to fix case 3.

k1 Rotate left k2

k2 k1 k3
A
k3
B C D
B A

C D
AVL Tree Building Example
15
6
Insert(15)
4

2 6

1 3 5 7 k1

16 k2
X
(null)
Z
Y (null)

15
AVL Tree Building Example
15
7
Insert(15) right-left double rotation

2 6
k1
1 3 5 7
k3
16
k2
Rotate right
15
AVL Tree Building Example
15
8
Insert(15) right-left double rotation

2 6
k1
1 3 5 7

Rotate left
k2
15
k3
16
AVL Tree Building Example
15
9
Insert(15) right-left double rotation

2 6
k2
1 3 5 15
k1 k3
7 16
AVL Tree Building Example
16
0
Insert(14): right-left double rotation

4
k1
2 6
k3
1 3 5 15
k2
Rotate right
7 16

14
AVL Tree Building Example
16
1
Insert(14): right-left double rotation

4
k1
2 6 Rotate left

k2
1 3 5 7

k3
15

14 16
AVL Tree Building Example
16
2
Insert(14): right-left double rotation

4
k2
2 7
k1 k3
1 3 6 15

5 14 16
AVL Tree Building Example
16
3
Insert(13): single rotation

4 Rotate left

2 7

1 3 6 15

5 14 16

13
AVL Tree Building Example
16
4
Insert(13): single rotation

4 15

2 6 14 16

1 3 5 13
C++ code for insert
16
5
TreeNode<int>*

avlInsert(TreeNode<int>* root, int info)
{
if( info < root->getInfo() ){
root->se tLeft(avlInsert(root->getLeft(), info));
int htdiff = height(root->getLeft()) –
height(root->getRight());
if( htdiff == 2 )
if( info < root->getLeft()->getInfo() )
root = singleRightRotation( root );
else
root = doubleLeftRightRotation( root );
}
C++ code for insert
16
6
TreeNode<int>*
avlInsert(TreeNode<int>* root, int info)
{

if( info < root->getInfo() ){
root->setLeft(avlInsert(root->getLeft(), info));
int htdiff = height(root->getLeft()) –
height(root->getRight());
if( htdiff == 2 )
if( info < root->getLeft()->getInfo() )
root = singleRightRotation( root );
else
root = doubleLeftRightRotation( root );
}
C++ code for insert
16
7
TreeNode<int>*
avlInsert(TreeNode<int>* root, int info)
{ Root of left subtree may change
if( info < root->getInfo() ){

root->setLeft(avlInsert(root->getLeft(), info));
int htdiff = height(root->getLeft()) –
height(root->getRight());
if( htdiff == 2 )
if( info < root->getLeft()->getInfo() )
root = singleRightRotation( root );
else
root = doubleLeftRightRotation( root );
}
C++ code for insert
16
8
TreeNode<int>*
avlInsert(TreeNode<int>* root, int info)
{
if( info < root->getInfo() ){
root->setLeft(avlInsert(root->getLeft(), info));

int htdiff = height(root->getLeft()) –
height(root->getRight());
if( htdiff == 2 )
if( info < root->getLeft()->getInfo() )
root = singleRightRotation( root );
else
root = doubleLeftRightRotation( root );
}
C++ code for insert
16
9
TreeNode<int>*
avlInsert(TreeNode<int>* root, int info)
{
if( info < root->getInfo() ){
root->setLeft(avlInsert(root->getLeft(), info));
int htdiff = height(root->getLeft()) –
height(root->getRight());

if( htdiff == 2 )
if( info < root->getLeft()->getInfo() )
root = singleRightRotation( root );
else
root = doubleLeftRightRotation( root );
}
C++ code for insert
17
0
TreeNode<int>*
avlInsert(TreeNode<int>* root, int info)
{
if( info < root->getInfo() ){
root->setLeft(avlInsert(root->getLeft(), info));
int htdiff = height(root->getLeft()) –
height(root->getRight());
if( htdiff == 2 )

if( info < root->getLeft()->getInfo() )
root = singleRightRotation( root ); Outside case

else
root = doubleLeftRightRotation( root
inside);
case
}
C++ code for insert
17
1
 else if(info > root->getInfo() ) {
root->setRight(avlInsert(root->getRight(),info));
int htdiff = height(root->getRight()) –
height(root->getLeft());
if( htdiff == 2 )
if( info > root->getRight()->getInfo() )
root = singleLeftRotation( root );
else
root = doubleRightLeftRotation( root );
}
// else a node with info is already in the tree. In
// case, reset the height of this root node.
int ht = Max(height(root->getLeft()),
height(root->getRight()));
root->setHeight( ht+1 ); // new height for root.
return root;
}
C++ code for insert
17
2
else if(info > root->getInfo() ) {
 root->setRight(avlInsert(root->getRight(),info));
int htdiff = height(root->getRight()) –
height(root->getLeft());
if( htdiff == 2 )
if( info > root->getRight()->getInfo() )
root = singleLeftRotation( root );
else
root = doubleRightLeftRotation( root );
}
// else a node with info is already in the tree. In
// case, reset the height of this root node.
int ht = Max(height(root->getLeft()),
height(root->getRight()));
root->setHeight( ht+1 ); // new height for root.
return root;
}
C++ code for insert
17
3
else if(info > root->getInfo() ) {
root->setRight(avlInsert(root->getRight(),info));

 int htdiff = height(root->getRight()) –


height(root->getLeft());
if( htdiff == 2 )
if( info > root->getRight()->getInfo() )
root = singleLeftRotation( root );
else
root = doubleRightLeftRotation( root );
}
// else a node with info is already in the tree. In
// case, reset the height of this root node.
int ht = Max(height(root->getLeft()),
height(root->getRight()));
root->setHeight( ht+1 ); // new height for root.
return root;
}
C++ code for insert
17
4
else if(info > root->getInfo() ) {
root->setRight(avlInsert(root->getRight(),info));
int htdiff = height(root->getRight()) –
height(root->getLeft());
if( htdiff == 2 )

if( info > root->getRight()->getInfo() )
root = singleLeftRotation( root );
else
root = doubleRightLeftRotation( root );
}
// else a node with info is already in the tree. In
// case, reset the height of this root node.
int ht = Max(height(root->getLeft()),
height(root->getRight()));
root->setHeight( ht+1 ); // new height for root.
return root;
}
C++ code for insert
17
5
else if(info > root->getInfo() ) {
root->setRight(avlInsert(root->getRight(),info));
int htdiff = height(root->getRight()) –
height(root->getLeft());
if( htdiff == 2 )
if( info > root->getRight()->getInfo() )

root = singleLeftRotation( root );
else
root = doubleRightLeftRotation( root );
}
// else a node with info is already in the tree. In
// case, reset the height of this root node.
int ht = Max(height(root->getLeft()),
height(root->getRight()));
root->setHeight( ht+1 ); // new height for root.
return root;
}
C++ code for insert
17
6
else if(info > root->getInfo() ) {
root->setRight(avlInsert(root->getRight(),info));
int htdiff = height(root->getRight()) –
height(root->getLeft());
if( htdiff == 2 )
if( info > root->getRight()->getInfo() )
root = singleLeftRotation( root );
else
root = doubleRightLeftRotation( root );
}
// else a node with info is already in the tree. In
// case, reset the height of this root node.

 int ht = Max(height(root->getLeft()),
height(root->getRight()));
root->setHeight( ht+1 ); // new height for root.
return root;
}
C++ code for insert
17
7
else if(info > root->getInfo() ) {
root->setRight(avlInsert(root->getRight(),info));
int htdiff = height(root->getRight()) –
height(root->getLeft());
if( htdiff == 2 )
if( info > root->getRight()->getInfo() )
root = singleLeftRotation( root );
else
root = doubleRightLeftRotation( root );
}
// else a node with info is already in the tree. In
// case, reset the height of this root node.
int ht = Max(height(root->getLeft()),
height(root->getRight()));
root->setHeight( ht+1 ); // new height for root.
 return root;
}

You might also like