§3 The Search Tree ADT -- Binary Search Trees 1. Definition 【Definition】A binary search tree is a binary tree.

Download Report

Transcript §3 The Search Tree ADT -- Binary Search Trees 1. Definition 【Definition】A binary search tree is a binary tree.

Slide 1

§3 The Search Tree ADT -- Binary Search Trees
1. Definition
【Definition】A binary search tree is a binary tree. It may be
(1)
(2)
(3)
(4)

empty. If it is not empty, it satisfies the following properties:
Every node has a key which is an integer, and the keys are
distinct.
The keys in a nonempty left subtree must be smaller than
the key in the root of the subtree.
The keys in a nonempty right subtree must be larger than
the key in the root of the subtree.
The left and right subtrees are also binary search trees.

30

5
2

1/22

60

40

20
70

65

15
80

12

10

25
22

§3 Binary Search Trees

2. ADT
Objects: A finite ordered list with zero or more elements.
Operations:

 SearchTree MakeEmpty( SearchTree T );
 Position Find( ElementType X, SearchTree T );
 Position FindMin( SearchTree T );
 Position FindMax( SearchTree T );
 SearchTree Insert( ElementType X, SearchTree T );
 SearchTree Delete( ElementType X, SearchTree T );
 ElementType Retrieve( Position P );

2/22

§3 Binary Search Trees

3. Implementations

 Find

Must this test
be performed first?

Position Find( ElementType X, SearchTree T )
{
if ( T == NULL )
These are
return NULL; /* not found in an empty tree */
tail recursions.
if ( X < T->Element ) /* if smaller than root */
return Find( X, T->Left ); /* search left subtree */
else
if ( X > T->Element ) /* if larger than root */
return Find( X, T->Right ); /* search right subtree */
else /* if X == root */
return T; /* found */
}
T( N ) = S ( N ) = O( d ) where d is the depth of X

3/22

§3 Binary Search Trees

Position Iter_Find( ElementType X, SearchTree T )
{
/* iterative version of Find */
while ( T ) {
if ( X == T->Element )
return T ; /* found */
if ( X < T->Element )
T = T->Left ; /*move down along left path */
else
T = T-> Right ; /* move down along right path */
} /* end while-loop */
return NULL ; /* not found */
}

4/22



FindMin

§3 Binary Search Trees

Position FindMin( SearchTree T )
T( N ) = O ( d )
{
if ( T == NULL )
return NULL; /* not found in an empty tree */
else
if ( T->Left == NULL ) return T; /* found left most */
else return FindMin( T->Left ); /* keep moving to left */
}

 FindMax
Position FindMax( SearchTree T )
T( N ) = O ( d )
{
if ( T != NULL )
while ( T->Right != NULL )
T = T->Right; /* keep moving to find right most */
return T; /* return NULL or the right most */
}

5/22

§3 Binary Search Trees

 Insert
Sketch of the idea:
Insert 80

30
5
2

40
25 35

Insert 35

Insert 25

6/22

 check if 80 is already in the tree
 80 > 40, so it must be the right child
80

of 40

Thisifis35
theis last
nodein the tree
 check
already
we encounter
 35search
< 40, so it must be the left child of 40
when
for the key number.
It will be the parent
 check if 25 is already in the tree
of the new node.
 25 > 5, so it must be the right child of 5

§3 Binary Search Trees
SearchTree Insert( ElementType X, SearchTree T )
{
if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct TreeNode ) );
if ( T == NULL )
FatalError( "Out of space!!!" );
else {
T->Element = X;
How would you
T->Left = T->Right = NULL; }
Handle
T(
N ) = duplicated
O(d)
} /* End creating a one-node tree */
Keys?
else /* If there is a tree */
if ( X < T->Element )
T->Left = Insert( X, T->Left );
else
if ( X > T->Element )
T->Right = Insert( X, T->Right );
/* Else X is in the tree already; we'll do nothing */
return T; /* Do not forget this line!! */
}

7/22

§3 Binary Search Trees

 Delete

 Delete a leaf nodeNote:
: Reset
its kinds
parentoflink
to NULL.
These
nodes
have: degree
atthe
most
1. by its single child.
 Delete a degree 1 node
Replace
node
 Delete a degree 2 node :

 Replace the node by the largest one in its left subtree or
the smallest one in its right subtree.
 Delete the replacing node from the subtree.

〖Example〗 Delete 60

40
20

Solution 1: reset left subtree.

10

60
55
30

50 70

Solution 2: reset right subtree.

45

55
52
52

8/22

§3 Binary Search Trees
SearchTree Delete( ElementType X, SearchTree T )
{ Position TmpCell;
if ( T == NULL ) Error( "Element not found" );
else if ( X < T->Element ) /* Go left */
T->Left = Delete( X, T->Left );
else if ( X > T->Element ) /* Go right */
T->Right = Delete( X, T->Right );
else /* Found element to be deleted */
if ( T->Left && T->Right ) { /* Two children */
/* Replace with smallest in right subtree */
TmpCell = FindMin( T->Right );
T->Element = TmpCell->Element;
T->Right = Delete( T->Element, T->Right ); } /* End if */
else { /* One or zero child */
TmpCell = T;
if ( T->Left == NULL ) /* Also handles 0 child */
T = T->Right;
else if ( T->Right == NULL ) T = T->Left;
free( TmpCell ); } /* End else 1 or 0 child */
return T;
T( N ) = O ( h ) where h is the height of the tree
}
9/22

§3 Binary Search Trees

Note:
If there are not many deletions, then lazy deletion
may be employed: add a flag field to each node, to mark
if a node is active or is deleted. Therefore we can delete
a node without actually freeing the space of that node.
If a deleted key is reinserted, we won’t have to call
malloc again.

While the number of deleted nodes
is the same as the number of active nodes
in the tree, will it seriously affect
the efficiency of the operations?

10/22

§3 Binary Search Trees

4. Average-Case Analysis
Question: Place n elements in a binary search tree. How
high can this tree be?

Answer: The height depends on the order of insertion.
〖Example〗 Given elements 1, 2, 3, 4, 5, 6, 7. Insert
them into a binary search tree in the orders:
4, 2, 1, 3, 6, 5, 7
and
1, 2, 3, 4, 5, 6, 7
4
2
1

6
3

5

h=2

11/22

h=6
7

§3 Binary Search Trees

【Definition】The internal path length for a tree of N nodes
N

is defined to be:

D( N )   d ( i ) , D(1)  0
i 1

where d( i ) is the
depth of work:
node i.
Home

【Theorem】 Assume that all binary search trees are equally
p.139 4.42
likely. Then the average D(N) (taken over all possible
Isomorphic
Trees
insertion sequences)
is O(N log
N). Thus the expected
depth of any node is O(log N).

p.140 4.45
D( N ) = D( i ) + D( N  i  1 ) + N  1
Threaded Trees

Proof:
Since all subtree sizes are
equally likely, the average
i nodes
value of both D( i ) and
N 1
D( N  i  1 ) is [ j  0 D( j )] N .

D( N ) 
12/22

2
N

[ j 0 D( j )]  N  1 =
N 1

root
+1
N  i  1 nodes

p.212-213

= O(N log N)

§4 AVL Trees
Target : Speed up searching (with insertion and
deletion)

root

Tool : Binary search trees
small

large

Problem : Although Tp = O( height ), but the
height can be as bad as O( N ).

13/22

§4 AVL Trees

〖Example〗 3 binary search trees obtained for the months
of the year
Jan

Average search time = ?3.5

Feb

Mar

Apr

June
Aug

May

July

Sept

Dec

Oct

Entered from Jan to Dec

AST = 6.5

Nov

July
Feb

Aug
Apr

May

Jan
Dec

Mar
June

A balanced tree
14/22

What if the months
are entered in
alphabetical order?

Average search time = ?3.1
Oct

Nov

Sept

§4 AVL Trees

Adelson-Velskii-Landis (AVL) Trees (1962)
【Definition】An empty binary tree is height balanced. If T is a
nonempty binary tree with TL and TR as its left and right
subtrees, then T is height balanced iff
(1) TL and TR are height balanced, and
The height of an empty tree
(2) | hL  hR |  1 where hL and hisR defined
are thetoheights
be –1. of TL and TR ,
respectively.

【Definition】The balance factor BF( node ) = hL  hR . In an
AVL tree, BF( node ) = 1, 0, or 1.
4

3
2
1
15/22

5

5

2
6

1
7

8
4 7

3

7

2
1

8
4

3

5

§4 AVL Trees

〖Example〗 Input the months

Mar

May

1
2
0

Mar

Nov
1
2
01
0

1
0

May

Single rotation

May
0

00

00

Mar

Nov

Nov

 The trouble maker Nov is in the right subtree’s right
subtree of the trouble finder Mar. Hence it is called an
RR rotation.
A is not necessarily
In general:
the root of the tree
1

A

RR
0

16/22

1

BR

B
BL

0

RR

BR

B

A

Rotation

AL

AL
BL

A

Insertion

B

0

2

BR
AL

BL

Aug

§4 AVL Trees

Apr
2
1
01
12

1
2
01
1

LL

May
210

00

Mar

Nov

1
010

Rotation

May
00

Aug

Nov

10

0

0

Aug

Apr

Mar

0

Apr
In general:
1
0

2

LL

A

1

Insertion

B

A

17/22

BR

LL

B
AR
BL

B

Rotation

AR
BL

0

BR

0

A
BL
BR

AR

§4 AVL Trees

Jan

21
2
1
01

Double Rotation

1
2
01
0

May

1
010

00

Aug

1
010

Nov

0

10

Apr

Mar

Aug

LR

0

Jan

Mar

1
0

May

0

0

Apr

Jan

0

Nov

Rotation

In general:
1
0

B

A

CL

Insertion

1

B

0

C
BL

2

LR

A

BL

CL

18/22

0 or 1

C

1 or 0

B

AR
CR

OR

0

Rotation

1

C

AR
CR

LR

BL

A
CL

CR
OR

AR

Dec

July

§4 AVL Trees

Feb

1
2
01
21

Mar

1
2
10

Aug

1
0

May

0

01

Apr

Jan

1
0

Nov

Dec

10

01
10

Aug

Jan

1
0

May
0

Nov

0

0

Apr

Feb

July

2

RL

July
0

Mar

1
02
1
0

Rotation
0

0

Dec

1
2
01
1

RL

0

Feb
In general:
1

A
0

RL
0

Insertion

B

1

C

AL
CL

A

CR

CL

19/22

B

0 or 1

C

1 or 0

A
CR

OR

0

Rotation

C

AL
BR

1

BR
AL

B
CL

CR
OR

BR

June

Oct

§4 AVL Trees

Sept
1
0

1
0 2
1
01
21

Jan
Mar
Jan
1
1
12
1
0 1
00
02
1
0
1
1
12
1
0
0 1
Dec
Mar
May
Dec Dec
Mar

1 10

1 Aug
Aug

Aug

0 0

0 Apr
Apr

Apr

0

0

Feb
Feb0
Feb

01
10 1
1
Jan

July
July

1
00

0 July
June

June

2
10

1
0
May
Nov
Nov

1
0 1
0
Nov 0
Oct
May
0
0

June

Note: Several bf’s
might be changed even if
we don’t need to reconstruct
the tree.

Oct 0
Sept

Another option is to keep a height field for each node.

20/22

§4 AVL Trees
AvlTree Insert( ElementType X, AvlTree T )
{ if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct AvlNode ) );
if ( T == NULL ) FatalError( "Out of space!!!" );
else { T->Element = X; T->Height = 0; T->Left = T->Right = NULL; }
} /* End creating a one-node tree */
else if ( X < T->Element ) { /* handle left insertion */
T->Left = Insert( X, T->Left );
if ( Height( T->Left ) - Height( T->Right ) == 2 ) /* not balanced */
if ( X < T->Left->Element ) /* LL Rotation */
T = SingleRotateWithLeft( T );
else /* LR Rotation */
T = DoubleRotateWithLeft( T ); } /* End left */
else if( X > T->Element ) { /* handle right insertion */
T->Right = Insert( X, T->Right );
if ( Height( T->Right ) - Height( T->Left ) == 2 ) /* not balanced */
if ( X > T->Right->Element ) /* RR Rotation */
T = SingleRotateWithRight( T );
else /* RL Rotation */
T = DoubleRotateWithRight( T ); } /* End right */
/* Else X is in the tree already; we'll do nothing */
T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
return T;
}

Home work:

p.136 4.16
Create an AVL Tree
p.136 4.22
Double Rotation

21/22

§4 AVL Trees

Let nh be the minimum number of nodes in a height balanced tree of
height h. Then the tree must look like

A
h2

A
h1

last question:
OROne
h1
h2  nh = nh1 + nh2 + 1

Obviously we have Tp = O( h )
where h is the height of the tree.
But h = ?

Fibonacci numbers:
F0 = 0, F1 = 1, Fi = Fi1 + Fi2 for i > 1
 nh = Fh+2  1, for h  0
i


1  1 5 
Fibonacci number theory gives that Fi 


1  1  5 
 nh 
5  2 
22/22

5

h 2

1

 h  O(lnn)

2




Slide 2

§3 The Search Tree ADT -- Binary Search Trees
1. Definition
【Definition】A binary search tree is a binary tree. It may be
(1)
(2)
(3)
(4)

empty. If it is not empty, it satisfies the following properties:
Every node has a key which is an integer, and the keys are
distinct.
The keys in a nonempty left subtree must be smaller than
the key in the root of the subtree.
The keys in a nonempty right subtree must be larger than
the key in the root of the subtree.
The left and right subtrees are also binary search trees.

30

5
2

1/22

60

40

20
70

65

15
80

12

10

25
22

§3 Binary Search Trees

2. ADT
Objects: A finite ordered list with zero or more elements.
Operations:

 SearchTree MakeEmpty( SearchTree T );
 Position Find( ElementType X, SearchTree T );
 Position FindMin( SearchTree T );
 Position FindMax( SearchTree T );
 SearchTree Insert( ElementType X, SearchTree T );
 SearchTree Delete( ElementType X, SearchTree T );
 ElementType Retrieve( Position P );

2/22

§3 Binary Search Trees

3. Implementations

 Find

Must this test
be performed first?

Position Find( ElementType X, SearchTree T )
{
if ( T == NULL )
These are
return NULL; /* not found in an empty tree */
tail recursions.
if ( X < T->Element ) /* if smaller than root */
return Find( X, T->Left ); /* search left subtree */
else
if ( X > T->Element ) /* if larger than root */
return Find( X, T->Right ); /* search right subtree */
else /* if X == root */
return T; /* found */
}
T( N ) = S ( N ) = O( d ) where d is the depth of X

3/22

§3 Binary Search Trees

Position Iter_Find( ElementType X, SearchTree T )
{
/* iterative version of Find */
while ( T ) {
if ( X == T->Element )
return T ; /* found */
if ( X < T->Element )
T = T->Left ; /*move down along left path */
else
T = T-> Right ; /* move down along right path */
} /* end while-loop */
return NULL ; /* not found */
}

4/22



FindMin

§3 Binary Search Trees

Position FindMin( SearchTree T )
T( N ) = O ( d )
{
if ( T == NULL )
return NULL; /* not found in an empty tree */
else
if ( T->Left == NULL ) return T; /* found left most */
else return FindMin( T->Left ); /* keep moving to left */
}

 FindMax
Position FindMax( SearchTree T )
T( N ) = O ( d )
{
if ( T != NULL )
while ( T->Right != NULL )
T = T->Right; /* keep moving to find right most */
return T; /* return NULL or the right most */
}

5/22

§3 Binary Search Trees

 Insert
Sketch of the idea:
Insert 80

30
5
2

40
25 35

Insert 35

Insert 25

6/22

 check if 80 is already in the tree
 80 > 40, so it must be the right child
80

of 40

Thisifis35
theis last
nodein the tree
 check
already
we encounter
 35search
< 40, so it must be the left child of 40
when
for the key number.
It will be the parent
 check if 25 is already in the tree
of the new node.
 25 > 5, so it must be the right child of 5

§3 Binary Search Trees
SearchTree Insert( ElementType X, SearchTree T )
{
if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct TreeNode ) );
if ( T == NULL )
FatalError( "Out of space!!!" );
else {
T->Element = X;
How would you
T->Left = T->Right = NULL; }
Handle
T(
N ) = duplicated
O(d)
} /* End creating a one-node tree */
Keys?
else /* If there is a tree */
if ( X < T->Element )
T->Left = Insert( X, T->Left );
else
if ( X > T->Element )
T->Right = Insert( X, T->Right );
/* Else X is in the tree already; we'll do nothing */
return T; /* Do not forget this line!! */
}

7/22

§3 Binary Search Trees

 Delete

 Delete a leaf nodeNote:
: Reset
its kinds
parentoflink
to NULL.
These
nodes
have: degree
atthe
most
1. by its single child.
 Delete a degree 1 node
Replace
node
 Delete a degree 2 node :

 Replace the node by the largest one in its left subtree or
the smallest one in its right subtree.
 Delete the replacing node from the subtree.

〖Example〗 Delete 60

40
20

Solution 1: reset left subtree.

10

60
55
30

50 70

Solution 2: reset right subtree.

45

55
52
52

8/22

§3 Binary Search Trees
SearchTree Delete( ElementType X, SearchTree T )
{ Position TmpCell;
if ( T == NULL ) Error( "Element not found" );
else if ( X < T->Element ) /* Go left */
T->Left = Delete( X, T->Left );
else if ( X > T->Element ) /* Go right */
T->Right = Delete( X, T->Right );
else /* Found element to be deleted */
if ( T->Left && T->Right ) { /* Two children */
/* Replace with smallest in right subtree */
TmpCell = FindMin( T->Right );
T->Element = TmpCell->Element;
T->Right = Delete( T->Element, T->Right ); } /* End if */
else { /* One or zero child */
TmpCell = T;
if ( T->Left == NULL ) /* Also handles 0 child */
T = T->Right;
else if ( T->Right == NULL ) T = T->Left;
free( TmpCell ); } /* End else 1 or 0 child */
return T;
T( N ) = O ( h ) where h is the height of the tree
}
9/22

§3 Binary Search Trees

Note:
If there are not many deletions, then lazy deletion
may be employed: add a flag field to each node, to mark
if a node is active or is deleted. Therefore we can delete
a node without actually freeing the space of that node.
If a deleted key is reinserted, we won’t have to call
malloc again.

While the number of deleted nodes
is the same as the number of active nodes
in the tree, will it seriously affect
the efficiency of the operations?

10/22

§3 Binary Search Trees

4. Average-Case Analysis
Question: Place n elements in a binary search tree. How
high can this tree be?

Answer: The height depends on the order of insertion.
〖Example〗 Given elements 1, 2, 3, 4, 5, 6, 7. Insert
them into a binary search tree in the orders:
4, 2, 1, 3, 6, 5, 7
and
1, 2, 3, 4, 5, 6, 7
4
2
1

6
3

5

h=2

11/22

h=6
7

§3 Binary Search Trees

【Definition】The internal path length for a tree of N nodes
N

is defined to be:

D( N )   d ( i ) , D(1)  0
i 1

where d( i ) is the
depth of work:
node i.
Home

【Theorem】 Assume that all binary search trees are equally
p.139 4.42
likely. Then the average D(N) (taken over all possible
Isomorphic
Trees
insertion sequences)
is O(N log
N). Thus the expected
depth of any node is O(log N).

p.140 4.45
D( N ) = D( i ) + D( N  i  1 ) + N  1
Threaded Trees

Proof:
Since all subtree sizes are
equally likely, the average
i nodes
value of both D( i ) and
N 1
D( N  i  1 ) is [ j  0 D( j )] N .

D( N ) 
12/22

2
N

[ j 0 D( j )]  N  1 =
N 1

root
+1
N  i  1 nodes

p.212-213

= O(N log N)

§4 AVL Trees
Target : Speed up searching (with insertion and
deletion)

root

Tool : Binary search trees
small

large

Problem : Although Tp = O( height ), but the
height can be as bad as O( N ).

13/22

§4 AVL Trees

〖Example〗 3 binary search trees obtained for the months
of the year
Jan

Average search time = ?3.5

Feb

Mar

Apr

June
Aug

May

July

Sept

Dec

Oct

Entered from Jan to Dec

AST = 6.5

Nov

July
Feb

Aug
Apr

May

Jan
Dec

Mar
June

A balanced tree
14/22

What if the months
are entered in
alphabetical order?

Average search time = ?3.1
Oct

Nov

Sept

§4 AVL Trees

Adelson-Velskii-Landis (AVL) Trees (1962)
【Definition】An empty binary tree is height balanced. If T is a
nonempty binary tree with TL and TR as its left and right
subtrees, then T is height balanced iff
(1) TL and TR are height balanced, and
The height of an empty tree
(2) | hL  hR |  1 where hL and hisR defined
are thetoheights
be –1. of TL and TR ,
respectively.

【Definition】The balance factor BF( node ) = hL  hR . In an
AVL tree, BF( node ) = 1, 0, or 1.
4

3
2
1
15/22

5

5

2
6

1
7

8
4 7

3

7

2
1

8
4

3

5

§4 AVL Trees

〖Example〗 Input the months

Mar

May

1
2
0

Mar

Nov
1
2
01
0

1
0

May

Single rotation

May
0

00

00

Mar

Nov

Nov

 The trouble maker Nov is in the right subtree’s right
subtree of the trouble finder Mar. Hence it is called an
RR rotation.
A is not necessarily
In general:
the root of the tree
1

A

RR
0

16/22

1

BR

B
BL

0

RR

BR

B

A

Rotation

AL

AL
BL

A

Insertion

B

0

2

BR
AL

BL

Aug

§4 AVL Trees

Apr
2
1
01
12

1
2
01
1

LL

May
210

00

Mar

Nov

1
010

Rotation

May
00

Aug

Nov

10

0

0

Aug

Apr

Mar

0

Apr
In general:
1
0

2

LL

A

1

Insertion

B

A

17/22

BR

LL

B
AR
BL

B

Rotation

AR
BL

0

BR

0

A
BL
BR

AR

§4 AVL Trees

Jan

21
2
1
01

Double Rotation

1
2
01
0

May

1
010

00

Aug

1
010

Nov

0

10

Apr

Mar

Aug

LR

0

Jan

Mar

1
0

May

0

0

Apr

Jan

0

Nov

Rotation

In general:
1
0

B

A

CL

Insertion

1

B

0

C
BL

2

LR

A

BL

CL

18/22

0 or 1

C

1 or 0

B

AR
CR

OR

0

Rotation

1

C

AR
CR

LR

BL

A
CL

CR
OR

AR

Dec

July

§4 AVL Trees

Feb

1
2
01
21

Mar

1
2
10

Aug

1
0

May

0

01

Apr

Jan

1
0

Nov

Dec

10

01
10

Aug

Jan

1
0

May
0

Nov

0

0

Apr

Feb

July

2

RL

July
0

Mar

1
02
1
0

Rotation
0

0

Dec

1
2
01
1

RL

0

Feb
In general:
1

A
0

RL
0

Insertion

B

1

C

AL
CL

A

CR

CL

19/22

B

0 or 1

C

1 or 0

A
CR

OR

0

Rotation

C

AL
BR

1

BR
AL

B
CL

CR
OR

BR

June

Oct

§4 AVL Trees

Sept
1
0

1
0 2
1
01
21

Jan
Mar
Jan
1
1
12
1
0 1
00
02
1
0
1
1
12
1
0
0 1
Dec
Mar
May
Dec Dec
Mar

1 10

1 Aug
Aug

Aug

0 0

0 Apr
Apr

Apr

0

0

Feb
Feb0
Feb

01
10 1
1
Jan

July
July

1
00

0 July
June

June

2
10

1
0
May
Nov
Nov

1
0 1
0
Nov 0
Oct
May
0
0

June

Note: Several bf’s
might be changed even if
we don’t need to reconstruct
the tree.

Oct 0
Sept

Another option is to keep a height field for each node.

20/22

§4 AVL Trees
AvlTree Insert( ElementType X, AvlTree T )
{ if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct AvlNode ) );
if ( T == NULL ) FatalError( "Out of space!!!" );
else { T->Element = X; T->Height = 0; T->Left = T->Right = NULL; }
} /* End creating a one-node tree */
else if ( X < T->Element ) { /* handle left insertion */
T->Left = Insert( X, T->Left );
if ( Height( T->Left ) - Height( T->Right ) == 2 ) /* not balanced */
if ( X < T->Left->Element ) /* LL Rotation */
T = SingleRotateWithLeft( T );
else /* LR Rotation */
T = DoubleRotateWithLeft( T ); } /* End left */
else if( X > T->Element ) { /* handle right insertion */
T->Right = Insert( X, T->Right );
if ( Height( T->Right ) - Height( T->Left ) == 2 ) /* not balanced */
if ( X > T->Right->Element ) /* RR Rotation */
T = SingleRotateWithRight( T );
else /* RL Rotation */
T = DoubleRotateWithRight( T ); } /* End right */
/* Else X is in the tree already; we'll do nothing */
T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
return T;
}

Home work:

p.136 4.16
Create an AVL Tree
p.136 4.22
Double Rotation

21/22

§4 AVL Trees

Let nh be the minimum number of nodes in a height balanced tree of
height h. Then the tree must look like

A
h2

A
h1

last question:
OROne
h1
h2  nh = nh1 + nh2 + 1

Obviously we have Tp = O( h )
where h is the height of the tree.
But h = ?

Fibonacci numbers:
F0 = 0, F1 = 1, Fi = Fi1 + Fi2 for i > 1
 nh = Fh+2  1, for h  0
i


1  1 5 
Fibonacci number theory gives that Fi 


1  1  5 
 nh 
5  2 
22/22

5

h 2

1

 h  O(lnn)

2




Slide 3

§3 The Search Tree ADT -- Binary Search Trees
1. Definition
【Definition】A binary search tree is a binary tree. It may be
(1)
(2)
(3)
(4)

empty. If it is not empty, it satisfies the following properties:
Every node has a key which is an integer, and the keys are
distinct.
The keys in a nonempty left subtree must be smaller than
the key in the root of the subtree.
The keys in a nonempty right subtree must be larger than
the key in the root of the subtree.
The left and right subtrees are also binary search trees.

30

5
2

1/22

60

40

20
70

65

15
80

12

10

25
22

§3 Binary Search Trees

2. ADT
Objects: A finite ordered list with zero or more elements.
Operations:

 SearchTree MakeEmpty( SearchTree T );
 Position Find( ElementType X, SearchTree T );
 Position FindMin( SearchTree T );
 Position FindMax( SearchTree T );
 SearchTree Insert( ElementType X, SearchTree T );
 SearchTree Delete( ElementType X, SearchTree T );
 ElementType Retrieve( Position P );

2/22

§3 Binary Search Trees

3. Implementations

 Find

Must this test
be performed first?

Position Find( ElementType X, SearchTree T )
{
if ( T == NULL )
These are
return NULL; /* not found in an empty tree */
tail recursions.
if ( X < T->Element ) /* if smaller than root */
return Find( X, T->Left ); /* search left subtree */
else
if ( X > T->Element ) /* if larger than root */
return Find( X, T->Right ); /* search right subtree */
else /* if X == root */
return T; /* found */
}
T( N ) = S ( N ) = O( d ) where d is the depth of X

3/22

§3 Binary Search Trees

Position Iter_Find( ElementType X, SearchTree T )
{
/* iterative version of Find */
while ( T ) {
if ( X == T->Element )
return T ; /* found */
if ( X < T->Element )
T = T->Left ; /*move down along left path */
else
T = T-> Right ; /* move down along right path */
} /* end while-loop */
return NULL ; /* not found */
}

4/22



FindMin

§3 Binary Search Trees

Position FindMin( SearchTree T )
T( N ) = O ( d )
{
if ( T == NULL )
return NULL; /* not found in an empty tree */
else
if ( T->Left == NULL ) return T; /* found left most */
else return FindMin( T->Left ); /* keep moving to left */
}

 FindMax
Position FindMax( SearchTree T )
T( N ) = O ( d )
{
if ( T != NULL )
while ( T->Right != NULL )
T = T->Right; /* keep moving to find right most */
return T; /* return NULL or the right most */
}

5/22

§3 Binary Search Trees

 Insert
Sketch of the idea:
Insert 80

30
5
2

40
25 35

Insert 35

Insert 25

6/22

 check if 80 is already in the tree
 80 > 40, so it must be the right child
80

of 40

Thisifis35
theis last
nodein the tree
 check
already
we encounter
 35search
< 40, so it must be the left child of 40
when
for the key number.
It will be the parent
 check if 25 is already in the tree
of the new node.
 25 > 5, so it must be the right child of 5

§3 Binary Search Trees
SearchTree Insert( ElementType X, SearchTree T )
{
if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct TreeNode ) );
if ( T == NULL )
FatalError( "Out of space!!!" );
else {
T->Element = X;
How would you
T->Left = T->Right = NULL; }
Handle
T(
N ) = duplicated
O(d)
} /* End creating a one-node tree */
Keys?
else /* If there is a tree */
if ( X < T->Element )
T->Left = Insert( X, T->Left );
else
if ( X > T->Element )
T->Right = Insert( X, T->Right );
/* Else X is in the tree already; we'll do nothing */
return T; /* Do not forget this line!! */
}

7/22

§3 Binary Search Trees

 Delete

 Delete a leaf nodeNote:
: Reset
its kinds
parentoflink
to NULL.
These
nodes
have: degree
atthe
most
1. by its single child.
 Delete a degree 1 node
Replace
node
 Delete a degree 2 node :

 Replace the node by the largest one in its left subtree or
the smallest one in its right subtree.
 Delete the replacing node from the subtree.

〖Example〗 Delete 60

40
20

Solution 1: reset left subtree.

10

60
55
30

50 70

Solution 2: reset right subtree.

45

55
52
52

8/22

§3 Binary Search Trees
SearchTree Delete( ElementType X, SearchTree T )
{ Position TmpCell;
if ( T == NULL ) Error( "Element not found" );
else if ( X < T->Element ) /* Go left */
T->Left = Delete( X, T->Left );
else if ( X > T->Element ) /* Go right */
T->Right = Delete( X, T->Right );
else /* Found element to be deleted */
if ( T->Left && T->Right ) { /* Two children */
/* Replace with smallest in right subtree */
TmpCell = FindMin( T->Right );
T->Element = TmpCell->Element;
T->Right = Delete( T->Element, T->Right ); } /* End if */
else { /* One or zero child */
TmpCell = T;
if ( T->Left == NULL ) /* Also handles 0 child */
T = T->Right;
else if ( T->Right == NULL ) T = T->Left;
free( TmpCell ); } /* End else 1 or 0 child */
return T;
T( N ) = O ( h ) where h is the height of the tree
}
9/22

§3 Binary Search Trees

Note:
If there are not many deletions, then lazy deletion
may be employed: add a flag field to each node, to mark
if a node is active or is deleted. Therefore we can delete
a node without actually freeing the space of that node.
If a deleted key is reinserted, we won’t have to call
malloc again.

While the number of deleted nodes
is the same as the number of active nodes
in the tree, will it seriously affect
the efficiency of the operations?

10/22

§3 Binary Search Trees

4. Average-Case Analysis
Question: Place n elements in a binary search tree. How
high can this tree be?

Answer: The height depends on the order of insertion.
〖Example〗 Given elements 1, 2, 3, 4, 5, 6, 7. Insert
them into a binary search tree in the orders:
4, 2, 1, 3, 6, 5, 7
and
1, 2, 3, 4, 5, 6, 7
4
2
1

6
3

5

h=2

11/22

h=6
7

§3 Binary Search Trees

【Definition】The internal path length for a tree of N nodes
N

is defined to be:

D( N )   d ( i ) , D(1)  0
i 1

where d( i ) is the
depth of work:
node i.
Home

【Theorem】 Assume that all binary search trees are equally
p.139 4.42
likely. Then the average D(N) (taken over all possible
Isomorphic
Trees
insertion sequences)
is O(N log
N). Thus the expected
depth of any node is O(log N).

p.140 4.45
D( N ) = D( i ) + D( N  i  1 ) + N  1
Threaded Trees

Proof:
Since all subtree sizes are
equally likely, the average
i nodes
value of both D( i ) and
N 1
D( N  i  1 ) is [ j  0 D( j )] N .

D( N ) 
12/22

2
N

[ j 0 D( j )]  N  1 =
N 1

root
+1
N  i  1 nodes

p.212-213

= O(N log N)

§4 AVL Trees
Target : Speed up searching (with insertion and
deletion)

root

Tool : Binary search trees
small

large

Problem : Although Tp = O( height ), but the
height can be as bad as O( N ).

13/22

§4 AVL Trees

〖Example〗 3 binary search trees obtained for the months
of the year
Jan

Average search time = ?3.5

Feb

Mar

Apr

June
Aug

May

July

Sept

Dec

Oct

Entered from Jan to Dec

AST = 6.5

Nov

July
Feb

Aug
Apr

May

Jan
Dec

Mar
June

A balanced tree
14/22

What if the months
are entered in
alphabetical order?

Average search time = ?3.1
Oct

Nov

Sept

§4 AVL Trees

Adelson-Velskii-Landis (AVL) Trees (1962)
【Definition】An empty binary tree is height balanced. If T is a
nonempty binary tree with TL and TR as its left and right
subtrees, then T is height balanced iff
(1) TL and TR are height balanced, and
The height of an empty tree
(2) | hL  hR |  1 where hL and hisR defined
are thetoheights
be –1. of TL and TR ,
respectively.

【Definition】The balance factor BF( node ) = hL  hR . In an
AVL tree, BF( node ) = 1, 0, or 1.
4

3
2
1
15/22

5

5

2
6

1
7

8
4 7

3

7

2
1

8
4

3

5

§4 AVL Trees

〖Example〗 Input the months

Mar

May

1
2
0

Mar

Nov
1
2
01
0

1
0

May

Single rotation

May
0

00

00

Mar

Nov

Nov

 The trouble maker Nov is in the right subtree’s right
subtree of the trouble finder Mar. Hence it is called an
RR rotation.
A is not necessarily
In general:
the root of the tree
1

A

RR
0

16/22

1

BR

B
BL

0

RR

BR

B

A

Rotation

AL

AL
BL

A

Insertion

B

0

2

BR
AL

BL

Aug

§4 AVL Trees

Apr
2
1
01
12

1
2
01
1

LL

May
210

00

Mar

Nov

1
010

Rotation

May
00

Aug

Nov

10

0

0

Aug

Apr

Mar

0

Apr
In general:
1
0

2

LL

A

1

Insertion

B

A

17/22

BR

LL

B
AR
BL

B

Rotation

AR
BL

0

BR

0

A
BL
BR

AR

§4 AVL Trees

Jan

21
2
1
01

Double Rotation

1
2
01
0

May

1
010

00

Aug

1
010

Nov

0

10

Apr

Mar

Aug

LR

0

Jan

Mar

1
0

May

0

0

Apr

Jan

0

Nov

Rotation

In general:
1
0

B

A

CL

Insertion

1

B

0

C
BL

2

LR

A

BL

CL

18/22

0 or 1

C

1 or 0

B

AR
CR

OR

0

Rotation

1

C

AR
CR

LR

BL

A
CL

CR
OR

AR

Dec

July

§4 AVL Trees

Feb

1
2
01
21

Mar

1
2
10

Aug

1
0

May

0

01

Apr

Jan

1
0

Nov

Dec

10

01
10

Aug

Jan

1
0

May
0

Nov

0

0

Apr

Feb

July

2

RL

July
0

Mar

1
02
1
0

Rotation
0

0

Dec

1
2
01
1

RL

0

Feb
In general:
1

A
0

RL
0

Insertion

B

1

C

AL
CL

A

CR

CL

19/22

B

0 or 1

C

1 or 0

A
CR

OR

0

Rotation

C

AL
BR

1

BR
AL

B
CL

CR
OR

BR

June

Oct

§4 AVL Trees

Sept
1
0

1
0 2
1
01
21

Jan
Mar
Jan
1
1
12
1
0 1
00
02
1
0
1
1
12
1
0
0 1
Dec
Mar
May
Dec Dec
Mar

1 10

1 Aug
Aug

Aug

0 0

0 Apr
Apr

Apr

0

0

Feb
Feb0
Feb

01
10 1
1
Jan

July
July

1
00

0 July
June

June

2
10

1
0
May
Nov
Nov

1
0 1
0
Nov 0
Oct
May
0
0

June

Note: Several bf’s
might be changed even if
we don’t need to reconstruct
the tree.

Oct 0
Sept

Another option is to keep a height field for each node.

20/22

§4 AVL Trees
AvlTree Insert( ElementType X, AvlTree T )
{ if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct AvlNode ) );
if ( T == NULL ) FatalError( "Out of space!!!" );
else { T->Element = X; T->Height = 0; T->Left = T->Right = NULL; }
} /* End creating a one-node tree */
else if ( X < T->Element ) { /* handle left insertion */
T->Left = Insert( X, T->Left );
if ( Height( T->Left ) - Height( T->Right ) == 2 ) /* not balanced */
if ( X < T->Left->Element ) /* LL Rotation */
T = SingleRotateWithLeft( T );
else /* LR Rotation */
T = DoubleRotateWithLeft( T ); } /* End left */
else if( X > T->Element ) { /* handle right insertion */
T->Right = Insert( X, T->Right );
if ( Height( T->Right ) - Height( T->Left ) == 2 ) /* not balanced */
if ( X > T->Right->Element ) /* RR Rotation */
T = SingleRotateWithRight( T );
else /* RL Rotation */
T = DoubleRotateWithRight( T ); } /* End right */
/* Else X is in the tree already; we'll do nothing */
T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
return T;
}

Home work:

p.136 4.16
Create an AVL Tree
p.136 4.22
Double Rotation

21/22

§4 AVL Trees

Let nh be the minimum number of nodes in a height balanced tree of
height h. Then the tree must look like

A
h2

A
h1

last question:
OROne
h1
h2  nh = nh1 + nh2 + 1

Obviously we have Tp = O( h )
where h is the height of the tree.
But h = ?

Fibonacci numbers:
F0 = 0, F1 = 1, Fi = Fi1 + Fi2 for i > 1
 nh = Fh+2  1, for h  0
i


1  1 5 
Fibonacci number theory gives that Fi 


1  1  5 
 nh 
5  2 
22/22

5

h 2

1

 h  O(lnn)

2




Slide 4

§3 The Search Tree ADT -- Binary Search Trees
1. Definition
【Definition】A binary search tree is a binary tree. It may be
(1)
(2)
(3)
(4)

empty. If it is not empty, it satisfies the following properties:
Every node has a key which is an integer, and the keys are
distinct.
The keys in a nonempty left subtree must be smaller than
the key in the root of the subtree.
The keys in a nonempty right subtree must be larger than
the key in the root of the subtree.
The left and right subtrees are also binary search trees.

30

5
2

1/22

60

40

20
70

65

15
80

12

10

25
22

§3 Binary Search Trees

2. ADT
Objects: A finite ordered list with zero or more elements.
Operations:

 SearchTree MakeEmpty( SearchTree T );
 Position Find( ElementType X, SearchTree T );
 Position FindMin( SearchTree T );
 Position FindMax( SearchTree T );
 SearchTree Insert( ElementType X, SearchTree T );
 SearchTree Delete( ElementType X, SearchTree T );
 ElementType Retrieve( Position P );

2/22

§3 Binary Search Trees

3. Implementations

 Find

Must this test
be performed first?

Position Find( ElementType X, SearchTree T )
{
if ( T == NULL )
These are
return NULL; /* not found in an empty tree */
tail recursions.
if ( X < T->Element ) /* if smaller than root */
return Find( X, T->Left ); /* search left subtree */
else
if ( X > T->Element ) /* if larger than root */
return Find( X, T->Right ); /* search right subtree */
else /* if X == root */
return T; /* found */
}
T( N ) = S ( N ) = O( d ) where d is the depth of X

3/22

§3 Binary Search Trees

Position Iter_Find( ElementType X, SearchTree T )
{
/* iterative version of Find */
while ( T ) {
if ( X == T->Element )
return T ; /* found */
if ( X < T->Element )
T = T->Left ; /*move down along left path */
else
T = T-> Right ; /* move down along right path */
} /* end while-loop */
return NULL ; /* not found */
}

4/22



FindMin

§3 Binary Search Trees

Position FindMin( SearchTree T )
T( N ) = O ( d )
{
if ( T == NULL )
return NULL; /* not found in an empty tree */
else
if ( T->Left == NULL ) return T; /* found left most */
else return FindMin( T->Left ); /* keep moving to left */
}

 FindMax
Position FindMax( SearchTree T )
T( N ) = O ( d )
{
if ( T != NULL )
while ( T->Right != NULL )
T = T->Right; /* keep moving to find right most */
return T; /* return NULL or the right most */
}

5/22

§3 Binary Search Trees

 Insert
Sketch of the idea:
Insert 80

30
5
2

40
25 35

Insert 35

Insert 25

6/22

 check if 80 is already in the tree
 80 > 40, so it must be the right child
80

of 40

Thisifis35
theis last
nodein the tree
 check
already
we encounter
 35search
< 40, so it must be the left child of 40
when
for the key number.
It will be the parent
 check if 25 is already in the tree
of the new node.
 25 > 5, so it must be the right child of 5

§3 Binary Search Trees
SearchTree Insert( ElementType X, SearchTree T )
{
if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct TreeNode ) );
if ( T == NULL )
FatalError( "Out of space!!!" );
else {
T->Element = X;
How would you
T->Left = T->Right = NULL; }
Handle
T(
N ) = duplicated
O(d)
} /* End creating a one-node tree */
Keys?
else /* If there is a tree */
if ( X < T->Element )
T->Left = Insert( X, T->Left );
else
if ( X > T->Element )
T->Right = Insert( X, T->Right );
/* Else X is in the tree already; we'll do nothing */
return T; /* Do not forget this line!! */
}

7/22

§3 Binary Search Trees

 Delete

 Delete a leaf nodeNote:
: Reset
its kinds
parentoflink
to NULL.
These
nodes
have: degree
atthe
most
1. by its single child.
 Delete a degree 1 node
Replace
node
 Delete a degree 2 node :

 Replace the node by the largest one in its left subtree or
the smallest one in its right subtree.
 Delete the replacing node from the subtree.

〖Example〗 Delete 60

40
20

Solution 1: reset left subtree.

10

60
55
30

50 70

Solution 2: reset right subtree.

45

55
52
52

8/22

§3 Binary Search Trees
SearchTree Delete( ElementType X, SearchTree T )
{ Position TmpCell;
if ( T == NULL ) Error( "Element not found" );
else if ( X < T->Element ) /* Go left */
T->Left = Delete( X, T->Left );
else if ( X > T->Element ) /* Go right */
T->Right = Delete( X, T->Right );
else /* Found element to be deleted */
if ( T->Left && T->Right ) { /* Two children */
/* Replace with smallest in right subtree */
TmpCell = FindMin( T->Right );
T->Element = TmpCell->Element;
T->Right = Delete( T->Element, T->Right ); } /* End if */
else { /* One or zero child */
TmpCell = T;
if ( T->Left == NULL ) /* Also handles 0 child */
T = T->Right;
else if ( T->Right == NULL ) T = T->Left;
free( TmpCell ); } /* End else 1 or 0 child */
return T;
T( N ) = O ( h ) where h is the height of the tree
}
9/22

§3 Binary Search Trees

Note:
If there are not many deletions, then lazy deletion
may be employed: add a flag field to each node, to mark
if a node is active or is deleted. Therefore we can delete
a node without actually freeing the space of that node.
If a deleted key is reinserted, we won’t have to call
malloc again.

While the number of deleted nodes
is the same as the number of active nodes
in the tree, will it seriously affect
the efficiency of the operations?

10/22

§3 Binary Search Trees

4. Average-Case Analysis
Question: Place n elements in a binary search tree. How
high can this tree be?

Answer: The height depends on the order of insertion.
〖Example〗 Given elements 1, 2, 3, 4, 5, 6, 7. Insert
them into a binary search tree in the orders:
4, 2, 1, 3, 6, 5, 7
and
1, 2, 3, 4, 5, 6, 7
4
2
1

6
3

5

h=2

11/22

h=6
7

§3 Binary Search Trees

【Definition】The internal path length for a tree of N nodes
N

is defined to be:

D( N )   d ( i ) , D(1)  0
i 1

where d( i ) is the
depth of work:
node i.
Home

【Theorem】 Assume that all binary search trees are equally
p.139 4.42
likely. Then the average D(N) (taken over all possible
Isomorphic
Trees
insertion sequences)
is O(N log
N). Thus the expected
depth of any node is O(log N).

p.140 4.45
D( N ) = D( i ) + D( N  i  1 ) + N  1
Threaded Trees

Proof:
Since all subtree sizes are
equally likely, the average
i nodes
value of both D( i ) and
N 1
D( N  i  1 ) is [ j  0 D( j )] N .

D( N ) 
12/22

2
N

[ j 0 D( j )]  N  1 =
N 1

root
+1
N  i  1 nodes

p.212-213

= O(N log N)

§4 AVL Trees
Target : Speed up searching (with insertion and
deletion)

root

Tool : Binary search trees
small

large

Problem : Although Tp = O( height ), but the
height can be as bad as O( N ).

13/22

§4 AVL Trees

〖Example〗 3 binary search trees obtained for the months
of the year
Jan

Average search time = ?3.5

Feb

Mar

Apr

June
Aug

May

July

Sept

Dec

Oct

Entered from Jan to Dec

AST = 6.5

Nov

July
Feb

Aug
Apr

May

Jan
Dec

Mar
June

A balanced tree
14/22

What if the months
are entered in
alphabetical order?

Average search time = ?3.1
Oct

Nov

Sept

§4 AVL Trees

Adelson-Velskii-Landis (AVL) Trees (1962)
【Definition】An empty binary tree is height balanced. If T is a
nonempty binary tree with TL and TR as its left and right
subtrees, then T is height balanced iff
(1) TL and TR are height balanced, and
The height of an empty tree
(2) | hL  hR |  1 where hL and hisR defined
are thetoheights
be –1. of TL and TR ,
respectively.

【Definition】The balance factor BF( node ) = hL  hR . In an
AVL tree, BF( node ) = 1, 0, or 1.
4

3
2
1
15/22

5

5

2
6

1
7

8
4 7

3

7

2
1

8
4

3

5

§4 AVL Trees

〖Example〗 Input the months

Mar

May

1
2
0

Mar

Nov
1
2
01
0

1
0

May

Single rotation

May
0

00

00

Mar

Nov

Nov

 The trouble maker Nov is in the right subtree’s right
subtree of the trouble finder Mar. Hence it is called an
RR rotation.
A is not necessarily
In general:
the root of the tree
1

A

RR
0

16/22

1

BR

B
BL

0

RR

BR

B

A

Rotation

AL

AL
BL

A

Insertion

B

0

2

BR
AL

BL

Aug

§4 AVL Trees

Apr
2
1
01
12

1
2
01
1

LL

May
210

00

Mar

Nov

1
010

Rotation

May
00

Aug

Nov

10

0

0

Aug

Apr

Mar

0

Apr
In general:
1
0

2

LL

A

1

Insertion

B

A

17/22

BR

LL

B
AR
BL

B

Rotation

AR
BL

0

BR

0

A
BL
BR

AR

§4 AVL Trees

Jan

21
2
1
01

Double Rotation

1
2
01
0

May

1
010

00

Aug

1
010

Nov

0

10

Apr

Mar

Aug

LR

0

Jan

Mar

1
0

May

0

0

Apr

Jan

0

Nov

Rotation

In general:
1
0

B

A

CL

Insertion

1

B

0

C
BL

2

LR

A

BL

CL

18/22

0 or 1

C

1 or 0

B

AR
CR

OR

0

Rotation

1

C

AR
CR

LR

BL

A
CL

CR
OR

AR

Dec

July

§4 AVL Trees

Feb

1
2
01
21

Mar

1
2
10

Aug

1
0

May

0

01

Apr

Jan

1
0

Nov

Dec

10

01
10

Aug

Jan

1
0

May
0

Nov

0

0

Apr

Feb

July

2

RL

July
0

Mar

1
02
1
0

Rotation
0

0

Dec

1
2
01
1

RL

0

Feb
In general:
1

A
0

RL
0

Insertion

B

1

C

AL
CL

A

CR

CL

19/22

B

0 or 1

C

1 or 0

A
CR

OR

0

Rotation

C

AL
BR

1

BR
AL

B
CL

CR
OR

BR

June

Oct

§4 AVL Trees

Sept
1
0

1
0 2
1
01
21

Jan
Mar
Jan
1
1
12
1
0 1
00
02
1
0
1
1
12
1
0
0 1
Dec
Mar
May
Dec Dec
Mar

1 10

1 Aug
Aug

Aug

0 0

0 Apr
Apr

Apr

0

0

Feb
Feb0
Feb

01
10 1
1
Jan

July
July

1
00

0 July
June

June

2
10

1
0
May
Nov
Nov

1
0 1
0
Nov 0
Oct
May
0
0

June

Note: Several bf’s
might be changed even if
we don’t need to reconstruct
the tree.

Oct 0
Sept

Another option is to keep a height field for each node.

20/22

§4 AVL Trees
AvlTree Insert( ElementType X, AvlTree T )
{ if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct AvlNode ) );
if ( T == NULL ) FatalError( "Out of space!!!" );
else { T->Element = X; T->Height = 0; T->Left = T->Right = NULL; }
} /* End creating a one-node tree */
else if ( X < T->Element ) { /* handle left insertion */
T->Left = Insert( X, T->Left );
if ( Height( T->Left ) - Height( T->Right ) == 2 ) /* not balanced */
if ( X < T->Left->Element ) /* LL Rotation */
T = SingleRotateWithLeft( T );
else /* LR Rotation */
T = DoubleRotateWithLeft( T ); } /* End left */
else if( X > T->Element ) { /* handle right insertion */
T->Right = Insert( X, T->Right );
if ( Height( T->Right ) - Height( T->Left ) == 2 ) /* not balanced */
if ( X > T->Right->Element ) /* RR Rotation */
T = SingleRotateWithRight( T );
else /* RL Rotation */
T = DoubleRotateWithRight( T ); } /* End right */
/* Else X is in the tree already; we'll do nothing */
T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
return T;
}

Home work:

p.136 4.16
Create an AVL Tree
p.136 4.22
Double Rotation

21/22

§4 AVL Trees

Let nh be the minimum number of nodes in a height balanced tree of
height h. Then the tree must look like

A
h2

A
h1

last question:
OROne
h1
h2  nh = nh1 + nh2 + 1

Obviously we have Tp = O( h )
where h is the height of the tree.
But h = ?

Fibonacci numbers:
F0 = 0, F1 = 1, Fi = Fi1 + Fi2 for i > 1
 nh = Fh+2  1, for h  0
i


1  1 5 
Fibonacci number theory gives that Fi 


1  1  5 
 nh 
5  2 
22/22

5

h 2

1

 h  O(lnn)

2




Slide 5

§3 The Search Tree ADT -- Binary Search Trees
1. Definition
【Definition】A binary search tree is a binary tree. It may be
(1)
(2)
(3)
(4)

empty. If it is not empty, it satisfies the following properties:
Every node has a key which is an integer, and the keys are
distinct.
The keys in a nonempty left subtree must be smaller than
the key in the root of the subtree.
The keys in a nonempty right subtree must be larger than
the key in the root of the subtree.
The left and right subtrees are also binary search trees.

30

5
2

1/22

60

40

20
70

65

15
80

12

10

25
22

§3 Binary Search Trees

2. ADT
Objects: A finite ordered list with zero or more elements.
Operations:

 SearchTree MakeEmpty( SearchTree T );
 Position Find( ElementType X, SearchTree T );
 Position FindMin( SearchTree T );
 Position FindMax( SearchTree T );
 SearchTree Insert( ElementType X, SearchTree T );
 SearchTree Delete( ElementType X, SearchTree T );
 ElementType Retrieve( Position P );

2/22

§3 Binary Search Trees

3. Implementations

 Find

Must this test
be performed first?

Position Find( ElementType X, SearchTree T )
{
if ( T == NULL )
These are
return NULL; /* not found in an empty tree */
tail recursions.
if ( X < T->Element ) /* if smaller than root */
return Find( X, T->Left ); /* search left subtree */
else
if ( X > T->Element ) /* if larger than root */
return Find( X, T->Right ); /* search right subtree */
else /* if X == root */
return T; /* found */
}
T( N ) = S ( N ) = O( d ) where d is the depth of X

3/22

§3 Binary Search Trees

Position Iter_Find( ElementType X, SearchTree T )
{
/* iterative version of Find */
while ( T ) {
if ( X == T->Element )
return T ; /* found */
if ( X < T->Element )
T = T->Left ; /*move down along left path */
else
T = T-> Right ; /* move down along right path */
} /* end while-loop */
return NULL ; /* not found */
}

4/22



FindMin

§3 Binary Search Trees

Position FindMin( SearchTree T )
T( N ) = O ( d )
{
if ( T == NULL )
return NULL; /* not found in an empty tree */
else
if ( T->Left == NULL ) return T; /* found left most */
else return FindMin( T->Left ); /* keep moving to left */
}

 FindMax
Position FindMax( SearchTree T )
T( N ) = O ( d )
{
if ( T != NULL )
while ( T->Right != NULL )
T = T->Right; /* keep moving to find right most */
return T; /* return NULL or the right most */
}

5/22

§3 Binary Search Trees

 Insert
Sketch of the idea:
Insert 80

30
5
2

40
25 35

Insert 35

Insert 25

6/22

 check if 80 is already in the tree
 80 > 40, so it must be the right child
80

of 40

Thisifis35
theis last
nodein the tree
 check
already
we encounter
 35search
< 40, so it must be the left child of 40
when
for the key number.
It will be the parent
 check if 25 is already in the tree
of the new node.
 25 > 5, so it must be the right child of 5

§3 Binary Search Trees
SearchTree Insert( ElementType X, SearchTree T )
{
if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct TreeNode ) );
if ( T == NULL )
FatalError( "Out of space!!!" );
else {
T->Element = X;
How would you
T->Left = T->Right = NULL; }
Handle
T(
N ) = duplicated
O(d)
} /* End creating a one-node tree */
Keys?
else /* If there is a tree */
if ( X < T->Element )
T->Left = Insert( X, T->Left );
else
if ( X > T->Element )
T->Right = Insert( X, T->Right );
/* Else X is in the tree already; we'll do nothing */
return T; /* Do not forget this line!! */
}

7/22

§3 Binary Search Trees

 Delete

 Delete a leaf nodeNote:
: Reset
its kinds
parentoflink
to NULL.
These
nodes
have: degree
atthe
most
1. by its single child.
 Delete a degree 1 node
Replace
node
 Delete a degree 2 node :

 Replace the node by the largest one in its left subtree or
the smallest one in its right subtree.
 Delete the replacing node from the subtree.

〖Example〗 Delete 60

40
20

Solution 1: reset left subtree.

10

60
55
30

50 70

Solution 2: reset right subtree.

45

55
52
52

8/22

§3 Binary Search Trees
SearchTree Delete( ElementType X, SearchTree T )
{ Position TmpCell;
if ( T == NULL ) Error( "Element not found" );
else if ( X < T->Element ) /* Go left */
T->Left = Delete( X, T->Left );
else if ( X > T->Element ) /* Go right */
T->Right = Delete( X, T->Right );
else /* Found element to be deleted */
if ( T->Left && T->Right ) { /* Two children */
/* Replace with smallest in right subtree */
TmpCell = FindMin( T->Right );
T->Element = TmpCell->Element;
T->Right = Delete( T->Element, T->Right ); } /* End if */
else { /* One or zero child */
TmpCell = T;
if ( T->Left == NULL ) /* Also handles 0 child */
T = T->Right;
else if ( T->Right == NULL ) T = T->Left;
free( TmpCell ); } /* End else 1 or 0 child */
return T;
T( N ) = O ( h ) where h is the height of the tree
}
9/22

§3 Binary Search Trees

Note:
If there are not many deletions, then lazy deletion
may be employed: add a flag field to each node, to mark
if a node is active or is deleted. Therefore we can delete
a node without actually freeing the space of that node.
If a deleted key is reinserted, we won’t have to call
malloc again.

While the number of deleted nodes
is the same as the number of active nodes
in the tree, will it seriously affect
the efficiency of the operations?

10/22

§3 Binary Search Trees

4. Average-Case Analysis
Question: Place n elements in a binary search tree. How
high can this tree be?

Answer: The height depends on the order of insertion.
〖Example〗 Given elements 1, 2, 3, 4, 5, 6, 7. Insert
them into a binary search tree in the orders:
4, 2, 1, 3, 6, 5, 7
and
1, 2, 3, 4, 5, 6, 7
4
2
1

6
3

5

h=2

11/22

h=6
7

§3 Binary Search Trees

【Definition】The internal path length for a tree of N nodes
N

is defined to be:

D( N )   d ( i ) , D(1)  0
i 1

where d( i ) is the
depth of work:
node i.
Home

【Theorem】 Assume that all binary search trees are equally
p.139 4.42
likely. Then the average D(N) (taken over all possible
Isomorphic
Trees
insertion sequences)
is O(N log
N). Thus the expected
depth of any node is O(log N).

p.140 4.45
D( N ) = D( i ) + D( N  i  1 ) + N  1
Threaded Trees

Proof:
Since all subtree sizes are
equally likely, the average
i nodes
value of both D( i ) and
N 1
D( N  i  1 ) is [ j  0 D( j )] N .

D( N ) 
12/22

2
N

[ j 0 D( j )]  N  1 =
N 1

root
+1
N  i  1 nodes

p.212-213

= O(N log N)

§4 AVL Trees
Target : Speed up searching (with insertion and
deletion)

root

Tool : Binary search trees
small

large

Problem : Although Tp = O( height ), but the
height can be as bad as O( N ).

13/22

§4 AVL Trees

〖Example〗 3 binary search trees obtained for the months
of the year
Jan

Average search time = ?3.5

Feb

Mar

Apr

June
Aug

May

July

Sept

Dec

Oct

Entered from Jan to Dec

AST = 6.5

Nov

July
Feb

Aug
Apr

May

Jan
Dec

Mar
June

A balanced tree
14/22

What if the months
are entered in
alphabetical order?

Average search time = ?3.1
Oct

Nov

Sept

§4 AVL Trees

Adelson-Velskii-Landis (AVL) Trees (1962)
【Definition】An empty binary tree is height balanced. If T is a
nonempty binary tree with TL and TR as its left and right
subtrees, then T is height balanced iff
(1) TL and TR are height balanced, and
The height of an empty tree
(2) | hL  hR |  1 where hL and hisR defined
are thetoheights
be –1. of TL and TR ,
respectively.

【Definition】The balance factor BF( node ) = hL  hR . In an
AVL tree, BF( node ) = 1, 0, or 1.
4

3
2
1
15/22

5

5

2
6

1
7

8
4 7

3

7

2
1

8
4

3

5

§4 AVL Trees

〖Example〗 Input the months

Mar

May

1
2
0

Mar

Nov
1
2
01
0

1
0

May

Single rotation

May
0

00

00

Mar

Nov

Nov

 The trouble maker Nov is in the right subtree’s right
subtree of the trouble finder Mar. Hence it is called an
RR rotation.
A is not necessarily
In general:
the root of the tree
1

A

RR
0

16/22

1

BR

B
BL

0

RR

BR

B

A

Rotation

AL

AL
BL

A

Insertion

B

0

2

BR
AL

BL

Aug

§4 AVL Trees

Apr
2
1
01
12

1
2
01
1

LL

May
210

00

Mar

Nov

1
010

Rotation

May
00

Aug

Nov

10

0

0

Aug

Apr

Mar

0

Apr
In general:
1
0

2

LL

A

1

Insertion

B

A

17/22

BR

LL

B
AR
BL

B

Rotation

AR
BL

0

BR

0

A
BL
BR

AR

§4 AVL Trees

Jan

21
2
1
01

Double Rotation

1
2
01
0

May

1
010

00

Aug

1
010

Nov

0

10

Apr

Mar

Aug

LR

0

Jan

Mar

1
0

May

0

0

Apr

Jan

0

Nov

Rotation

In general:
1
0

B

A

CL

Insertion

1

B

0

C
BL

2

LR

A

BL

CL

18/22

0 or 1

C

1 or 0

B

AR
CR

OR

0

Rotation

1

C

AR
CR

LR

BL

A
CL

CR
OR

AR

Dec

July

§4 AVL Trees

Feb

1
2
01
21

Mar

1
2
10

Aug

1
0

May

0

01

Apr

Jan

1
0

Nov

Dec

10

01
10

Aug

Jan

1
0

May
0

Nov

0

0

Apr

Feb

July

2

RL

July
0

Mar

1
02
1
0

Rotation
0

0

Dec

1
2
01
1

RL

0

Feb
In general:
1

A
0

RL
0

Insertion

B

1

C

AL
CL

A

CR

CL

19/22

B

0 or 1

C

1 or 0

A
CR

OR

0

Rotation

C

AL
BR

1

BR
AL

B
CL

CR
OR

BR

June

Oct

§4 AVL Trees

Sept
1
0

1
0 2
1
01
21

Jan
Mar
Jan
1
1
12
1
0 1
00
02
1
0
1
1
12
1
0
0 1
Dec
Mar
May
Dec Dec
Mar

1 10

1 Aug
Aug

Aug

0 0

0 Apr
Apr

Apr

0

0

Feb
Feb0
Feb

01
10 1
1
Jan

July
July

1
00

0 July
June

June

2
10

1
0
May
Nov
Nov

1
0 1
0
Nov 0
Oct
May
0
0

June

Note: Several bf’s
might be changed even if
we don’t need to reconstruct
the tree.

Oct 0
Sept

Another option is to keep a height field for each node.

20/22

§4 AVL Trees
AvlTree Insert( ElementType X, AvlTree T )
{ if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct AvlNode ) );
if ( T == NULL ) FatalError( "Out of space!!!" );
else { T->Element = X; T->Height = 0; T->Left = T->Right = NULL; }
} /* End creating a one-node tree */
else if ( X < T->Element ) { /* handle left insertion */
T->Left = Insert( X, T->Left );
if ( Height( T->Left ) - Height( T->Right ) == 2 ) /* not balanced */
if ( X < T->Left->Element ) /* LL Rotation */
T = SingleRotateWithLeft( T );
else /* LR Rotation */
T = DoubleRotateWithLeft( T ); } /* End left */
else if( X > T->Element ) { /* handle right insertion */
T->Right = Insert( X, T->Right );
if ( Height( T->Right ) - Height( T->Left ) == 2 ) /* not balanced */
if ( X > T->Right->Element ) /* RR Rotation */
T = SingleRotateWithRight( T );
else /* RL Rotation */
T = DoubleRotateWithRight( T ); } /* End right */
/* Else X is in the tree already; we'll do nothing */
T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
return T;
}

Home work:

p.136 4.16
Create an AVL Tree
p.136 4.22
Double Rotation

21/22

§4 AVL Trees

Let nh be the minimum number of nodes in a height balanced tree of
height h. Then the tree must look like

A
h2

A
h1

last question:
OROne
h1
h2  nh = nh1 + nh2 + 1

Obviously we have Tp = O( h )
where h is the height of the tree.
But h = ?

Fibonacci numbers:
F0 = 0, F1 = 1, Fi = Fi1 + Fi2 for i > 1
 nh = Fh+2  1, for h  0
i


1  1 5 
Fibonacci number theory gives that Fi 


1  1  5 
 nh 
5  2 
22/22

5

h 2

1

 h  O(lnn)

2




Slide 6

§3 The Search Tree ADT -- Binary Search Trees
1. Definition
【Definition】A binary search tree is a binary tree. It may be
(1)
(2)
(3)
(4)

empty. If it is not empty, it satisfies the following properties:
Every node has a key which is an integer, and the keys are
distinct.
The keys in a nonempty left subtree must be smaller than
the key in the root of the subtree.
The keys in a nonempty right subtree must be larger than
the key in the root of the subtree.
The left and right subtrees are also binary search trees.

30

5
2

1/22

60

40

20
70

65

15
80

12

10

25
22

§3 Binary Search Trees

2. ADT
Objects: A finite ordered list with zero or more elements.
Operations:

 SearchTree MakeEmpty( SearchTree T );
 Position Find( ElementType X, SearchTree T );
 Position FindMin( SearchTree T );
 Position FindMax( SearchTree T );
 SearchTree Insert( ElementType X, SearchTree T );
 SearchTree Delete( ElementType X, SearchTree T );
 ElementType Retrieve( Position P );

2/22

§3 Binary Search Trees

3. Implementations

 Find

Must this test
be performed first?

Position Find( ElementType X, SearchTree T )
{
if ( T == NULL )
These are
return NULL; /* not found in an empty tree */
tail recursions.
if ( X < T->Element ) /* if smaller than root */
return Find( X, T->Left ); /* search left subtree */
else
if ( X > T->Element ) /* if larger than root */
return Find( X, T->Right ); /* search right subtree */
else /* if X == root */
return T; /* found */
}
T( N ) = S ( N ) = O( d ) where d is the depth of X

3/22

§3 Binary Search Trees

Position Iter_Find( ElementType X, SearchTree T )
{
/* iterative version of Find */
while ( T ) {
if ( X == T->Element )
return T ; /* found */
if ( X < T->Element )
T = T->Left ; /*move down along left path */
else
T = T-> Right ; /* move down along right path */
} /* end while-loop */
return NULL ; /* not found */
}

4/22



FindMin

§3 Binary Search Trees

Position FindMin( SearchTree T )
T( N ) = O ( d )
{
if ( T == NULL )
return NULL; /* not found in an empty tree */
else
if ( T->Left == NULL ) return T; /* found left most */
else return FindMin( T->Left ); /* keep moving to left */
}

 FindMax
Position FindMax( SearchTree T )
T( N ) = O ( d )
{
if ( T != NULL )
while ( T->Right != NULL )
T = T->Right; /* keep moving to find right most */
return T; /* return NULL or the right most */
}

5/22

§3 Binary Search Trees

 Insert
Sketch of the idea:
Insert 80

30
5
2

40
25 35

Insert 35

Insert 25

6/22

 check if 80 is already in the tree
 80 > 40, so it must be the right child
80

of 40

Thisifis35
theis last
nodein the tree
 check
already
we encounter
 35search
< 40, so it must be the left child of 40
when
for the key number.
It will be the parent
 check if 25 is already in the tree
of the new node.
 25 > 5, so it must be the right child of 5

§3 Binary Search Trees
SearchTree Insert( ElementType X, SearchTree T )
{
if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct TreeNode ) );
if ( T == NULL )
FatalError( "Out of space!!!" );
else {
T->Element = X;
How would you
T->Left = T->Right = NULL; }
Handle
T(
N ) = duplicated
O(d)
} /* End creating a one-node tree */
Keys?
else /* If there is a tree */
if ( X < T->Element )
T->Left = Insert( X, T->Left );
else
if ( X > T->Element )
T->Right = Insert( X, T->Right );
/* Else X is in the tree already; we'll do nothing */
return T; /* Do not forget this line!! */
}

7/22

§3 Binary Search Trees

 Delete

 Delete a leaf nodeNote:
: Reset
its kinds
parentoflink
to NULL.
These
nodes
have: degree
atthe
most
1. by its single child.
 Delete a degree 1 node
Replace
node
 Delete a degree 2 node :

 Replace the node by the largest one in its left subtree or
the smallest one in its right subtree.
 Delete the replacing node from the subtree.

〖Example〗 Delete 60

40
20

Solution 1: reset left subtree.

10

60
55
30

50 70

Solution 2: reset right subtree.

45

55
52
52

8/22

§3 Binary Search Trees
SearchTree Delete( ElementType X, SearchTree T )
{ Position TmpCell;
if ( T == NULL ) Error( "Element not found" );
else if ( X < T->Element ) /* Go left */
T->Left = Delete( X, T->Left );
else if ( X > T->Element ) /* Go right */
T->Right = Delete( X, T->Right );
else /* Found element to be deleted */
if ( T->Left && T->Right ) { /* Two children */
/* Replace with smallest in right subtree */
TmpCell = FindMin( T->Right );
T->Element = TmpCell->Element;
T->Right = Delete( T->Element, T->Right ); } /* End if */
else { /* One or zero child */
TmpCell = T;
if ( T->Left == NULL ) /* Also handles 0 child */
T = T->Right;
else if ( T->Right == NULL ) T = T->Left;
free( TmpCell ); } /* End else 1 or 0 child */
return T;
T( N ) = O ( h ) where h is the height of the tree
}
9/22

§3 Binary Search Trees

Note:
If there are not many deletions, then lazy deletion
may be employed: add a flag field to each node, to mark
if a node is active or is deleted. Therefore we can delete
a node without actually freeing the space of that node.
If a deleted key is reinserted, we won’t have to call
malloc again.

While the number of deleted nodes
is the same as the number of active nodes
in the tree, will it seriously affect
the efficiency of the operations?

10/22

§3 Binary Search Trees

4. Average-Case Analysis
Question: Place n elements in a binary search tree. How
high can this tree be?

Answer: The height depends on the order of insertion.
〖Example〗 Given elements 1, 2, 3, 4, 5, 6, 7. Insert
them into a binary search tree in the orders:
4, 2, 1, 3, 6, 5, 7
and
1, 2, 3, 4, 5, 6, 7
4
2
1

6
3

5

h=2

11/22

h=6
7

§3 Binary Search Trees

【Definition】The internal path length for a tree of N nodes
N

is defined to be:

D( N )   d ( i ) , D(1)  0
i 1

where d( i ) is the
depth of work:
node i.
Home

【Theorem】 Assume that all binary search trees are equally
p.139 4.42
likely. Then the average D(N) (taken over all possible
Isomorphic
Trees
insertion sequences)
is O(N log
N). Thus the expected
depth of any node is O(log N).

p.140 4.45
D( N ) = D( i ) + D( N  i  1 ) + N  1
Threaded Trees

Proof:
Since all subtree sizes are
equally likely, the average
i nodes
value of both D( i ) and
N 1
D( N  i  1 ) is [ j  0 D( j )] N .

D( N ) 
12/22

2
N

[ j 0 D( j )]  N  1 =
N 1

root
+1
N  i  1 nodes

p.212-213

= O(N log N)

§4 AVL Trees
Target : Speed up searching (with insertion and
deletion)

root

Tool : Binary search trees
small

large

Problem : Although Tp = O( height ), but the
height can be as bad as O( N ).

13/22

§4 AVL Trees

〖Example〗 3 binary search trees obtained for the months
of the year
Jan

Average search time = ?3.5

Feb

Mar

Apr

June
Aug

May

July

Sept

Dec

Oct

Entered from Jan to Dec

AST = 6.5

Nov

July
Feb

Aug
Apr

May

Jan
Dec

Mar
June

A balanced tree
14/22

What if the months
are entered in
alphabetical order?

Average search time = ?3.1
Oct

Nov

Sept

§4 AVL Trees

Adelson-Velskii-Landis (AVL) Trees (1962)
【Definition】An empty binary tree is height balanced. If T is a
nonempty binary tree with TL and TR as its left and right
subtrees, then T is height balanced iff
(1) TL and TR are height balanced, and
The height of an empty tree
(2) | hL  hR |  1 where hL and hisR defined
are thetoheights
be –1. of TL and TR ,
respectively.

【Definition】The balance factor BF( node ) = hL  hR . In an
AVL tree, BF( node ) = 1, 0, or 1.
4

3
2
1
15/22

5

5

2
6

1
7

8
4 7

3

7

2
1

8
4

3

5

§4 AVL Trees

〖Example〗 Input the months

Mar

May

1
2
0

Mar

Nov
1
2
01
0

1
0

May

Single rotation

May
0

00

00

Mar

Nov

Nov

 The trouble maker Nov is in the right subtree’s right
subtree of the trouble finder Mar. Hence it is called an
RR rotation.
A is not necessarily
In general:
the root of the tree
1

A

RR
0

16/22

1

BR

B
BL

0

RR

BR

B

A

Rotation

AL

AL
BL

A

Insertion

B

0

2

BR
AL

BL

Aug

§4 AVL Trees

Apr
2
1
01
12

1
2
01
1

LL

May
210

00

Mar

Nov

1
010

Rotation

May
00

Aug

Nov

10

0

0

Aug

Apr

Mar

0

Apr
In general:
1
0

2

LL

A

1

Insertion

B

A

17/22

BR

LL

B
AR
BL

B

Rotation

AR
BL

0

BR

0

A
BL
BR

AR

§4 AVL Trees

Jan

21
2
1
01

Double Rotation

1
2
01
0

May

1
010

00

Aug

1
010

Nov

0

10

Apr

Mar

Aug

LR

0

Jan

Mar

1
0

May

0

0

Apr

Jan

0

Nov

Rotation

In general:
1
0

B

A

CL

Insertion

1

B

0

C
BL

2

LR

A

BL

CL

18/22

0 or 1

C

1 or 0

B

AR
CR

OR

0

Rotation

1

C

AR
CR

LR

BL

A
CL

CR
OR

AR

Dec

July

§4 AVL Trees

Feb

1
2
01
21

Mar

1
2
10

Aug

1
0

May

0

01

Apr

Jan

1
0

Nov

Dec

10

01
10

Aug

Jan

1
0

May
0

Nov

0

0

Apr

Feb

July

2

RL

July
0

Mar

1
02
1
0

Rotation
0

0

Dec

1
2
01
1

RL

0

Feb
In general:
1

A
0

RL
0

Insertion

B

1

C

AL
CL

A

CR

CL

19/22

B

0 or 1

C

1 or 0

A
CR

OR

0

Rotation

C

AL
BR

1

BR
AL

B
CL

CR
OR

BR

June

Oct

§4 AVL Trees

Sept
1
0

1
0 2
1
01
21

Jan
Mar
Jan
1
1
12
1
0 1
00
02
1
0
1
1
12
1
0
0 1
Dec
Mar
May
Dec Dec
Mar

1 10

1 Aug
Aug

Aug

0 0

0 Apr
Apr

Apr

0

0

Feb
Feb0
Feb

01
10 1
1
Jan

July
July

1
00

0 July
June

June

2
10

1
0
May
Nov
Nov

1
0 1
0
Nov 0
Oct
May
0
0

June

Note: Several bf’s
might be changed even if
we don’t need to reconstruct
the tree.

Oct 0
Sept

Another option is to keep a height field for each node.

20/22

§4 AVL Trees
AvlTree Insert( ElementType X, AvlTree T )
{ if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct AvlNode ) );
if ( T == NULL ) FatalError( "Out of space!!!" );
else { T->Element = X; T->Height = 0; T->Left = T->Right = NULL; }
} /* End creating a one-node tree */
else if ( X < T->Element ) { /* handle left insertion */
T->Left = Insert( X, T->Left );
if ( Height( T->Left ) - Height( T->Right ) == 2 ) /* not balanced */
if ( X < T->Left->Element ) /* LL Rotation */
T = SingleRotateWithLeft( T );
else /* LR Rotation */
T = DoubleRotateWithLeft( T ); } /* End left */
else if( X > T->Element ) { /* handle right insertion */
T->Right = Insert( X, T->Right );
if ( Height( T->Right ) - Height( T->Left ) == 2 ) /* not balanced */
if ( X > T->Right->Element ) /* RR Rotation */
T = SingleRotateWithRight( T );
else /* RL Rotation */
T = DoubleRotateWithRight( T ); } /* End right */
/* Else X is in the tree already; we'll do nothing */
T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
return T;
}

Home work:

p.136 4.16
Create an AVL Tree
p.136 4.22
Double Rotation

21/22

§4 AVL Trees

Let nh be the minimum number of nodes in a height balanced tree of
height h. Then the tree must look like

A
h2

A
h1

last question:
OROne
h1
h2  nh = nh1 + nh2 + 1

Obviously we have Tp = O( h )
where h is the height of the tree.
But h = ?

Fibonacci numbers:
F0 = 0, F1 = 1, Fi = Fi1 + Fi2 for i > 1
 nh = Fh+2  1, for h  0
i


1  1 5 
Fibonacci number theory gives that Fi 


1  1  5 
 nh 
5  2 
22/22

5

h 2

1

 h  O(lnn)

2




Slide 7

§3 The Search Tree ADT -- Binary Search Trees
1. Definition
【Definition】A binary search tree is a binary tree. It may be
(1)
(2)
(3)
(4)

empty. If it is not empty, it satisfies the following properties:
Every node has a key which is an integer, and the keys are
distinct.
The keys in a nonempty left subtree must be smaller than
the key in the root of the subtree.
The keys in a nonempty right subtree must be larger than
the key in the root of the subtree.
The left and right subtrees are also binary search trees.

30

5
2

1/22

60

40

20
70

65

15
80

12

10

25
22

§3 Binary Search Trees

2. ADT
Objects: A finite ordered list with zero or more elements.
Operations:

 SearchTree MakeEmpty( SearchTree T );
 Position Find( ElementType X, SearchTree T );
 Position FindMin( SearchTree T );
 Position FindMax( SearchTree T );
 SearchTree Insert( ElementType X, SearchTree T );
 SearchTree Delete( ElementType X, SearchTree T );
 ElementType Retrieve( Position P );

2/22

§3 Binary Search Trees

3. Implementations

 Find

Must this test
be performed first?

Position Find( ElementType X, SearchTree T )
{
if ( T == NULL )
These are
return NULL; /* not found in an empty tree */
tail recursions.
if ( X < T->Element ) /* if smaller than root */
return Find( X, T->Left ); /* search left subtree */
else
if ( X > T->Element ) /* if larger than root */
return Find( X, T->Right ); /* search right subtree */
else /* if X == root */
return T; /* found */
}
T( N ) = S ( N ) = O( d ) where d is the depth of X

3/22

§3 Binary Search Trees

Position Iter_Find( ElementType X, SearchTree T )
{
/* iterative version of Find */
while ( T ) {
if ( X == T->Element )
return T ; /* found */
if ( X < T->Element )
T = T->Left ; /*move down along left path */
else
T = T-> Right ; /* move down along right path */
} /* end while-loop */
return NULL ; /* not found */
}

4/22



FindMin

§3 Binary Search Trees

Position FindMin( SearchTree T )
T( N ) = O ( d )
{
if ( T == NULL )
return NULL; /* not found in an empty tree */
else
if ( T->Left == NULL ) return T; /* found left most */
else return FindMin( T->Left ); /* keep moving to left */
}

 FindMax
Position FindMax( SearchTree T )
T( N ) = O ( d )
{
if ( T != NULL )
while ( T->Right != NULL )
T = T->Right; /* keep moving to find right most */
return T; /* return NULL or the right most */
}

5/22

§3 Binary Search Trees

 Insert
Sketch of the idea:
Insert 80

30
5
2

40
25 35

Insert 35

Insert 25

6/22

 check if 80 is already in the tree
 80 > 40, so it must be the right child
80

of 40

Thisifis35
theis last
nodein the tree
 check
already
we encounter
 35search
< 40, so it must be the left child of 40
when
for the key number.
It will be the parent
 check if 25 is already in the tree
of the new node.
 25 > 5, so it must be the right child of 5

§3 Binary Search Trees
SearchTree Insert( ElementType X, SearchTree T )
{
if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct TreeNode ) );
if ( T == NULL )
FatalError( "Out of space!!!" );
else {
T->Element = X;
How would you
T->Left = T->Right = NULL; }
Handle
T(
N ) = duplicated
O(d)
} /* End creating a one-node tree */
Keys?
else /* If there is a tree */
if ( X < T->Element )
T->Left = Insert( X, T->Left );
else
if ( X > T->Element )
T->Right = Insert( X, T->Right );
/* Else X is in the tree already; we'll do nothing */
return T; /* Do not forget this line!! */
}

7/22

§3 Binary Search Trees

 Delete

 Delete a leaf nodeNote:
: Reset
its kinds
parentoflink
to NULL.
These
nodes
have: degree
atthe
most
1. by its single child.
 Delete a degree 1 node
Replace
node
 Delete a degree 2 node :

 Replace the node by the largest one in its left subtree or
the smallest one in its right subtree.
 Delete the replacing node from the subtree.

〖Example〗 Delete 60

40
20

Solution 1: reset left subtree.

10

60
55
30

50 70

Solution 2: reset right subtree.

45

55
52
52

8/22

§3 Binary Search Trees
SearchTree Delete( ElementType X, SearchTree T )
{ Position TmpCell;
if ( T == NULL ) Error( "Element not found" );
else if ( X < T->Element ) /* Go left */
T->Left = Delete( X, T->Left );
else if ( X > T->Element ) /* Go right */
T->Right = Delete( X, T->Right );
else /* Found element to be deleted */
if ( T->Left && T->Right ) { /* Two children */
/* Replace with smallest in right subtree */
TmpCell = FindMin( T->Right );
T->Element = TmpCell->Element;
T->Right = Delete( T->Element, T->Right ); } /* End if */
else { /* One or zero child */
TmpCell = T;
if ( T->Left == NULL ) /* Also handles 0 child */
T = T->Right;
else if ( T->Right == NULL ) T = T->Left;
free( TmpCell ); } /* End else 1 or 0 child */
return T;
T( N ) = O ( h ) where h is the height of the tree
}
9/22

§3 Binary Search Trees

Note:
If there are not many deletions, then lazy deletion
may be employed: add a flag field to each node, to mark
if a node is active or is deleted. Therefore we can delete
a node without actually freeing the space of that node.
If a deleted key is reinserted, we won’t have to call
malloc again.

While the number of deleted nodes
is the same as the number of active nodes
in the tree, will it seriously affect
the efficiency of the operations?

10/22

§3 Binary Search Trees

4. Average-Case Analysis
Question: Place n elements in a binary search tree. How
high can this tree be?

Answer: The height depends on the order of insertion.
〖Example〗 Given elements 1, 2, 3, 4, 5, 6, 7. Insert
them into a binary search tree in the orders:
4, 2, 1, 3, 6, 5, 7
and
1, 2, 3, 4, 5, 6, 7
4
2
1

6
3

5

h=2

11/22

h=6
7

§3 Binary Search Trees

【Definition】The internal path length for a tree of N nodes
N

is defined to be:

D( N )   d ( i ) , D(1)  0
i 1

where d( i ) is the
depth of work:
node i.
Home

【Theorem】 Assume that all binary search trees are equally
p.139 4.42
likely. Then the average D(N) (taken over all possible
Isomorphic
Trees
insertion sequences)
is O(N log
N). Thus the expected
depth of any node is O(log N).

p.140 4.45
D( N ) = D( i ) + D( N  i  1 ) + N  1
Threaded Trees

Proof:
Since all subtree sizes are
equally likely, the average
i nodes
value of both D( i ) and
N 1
D( N  i  1 ) is [ j  0 D( j )] N .

D( N ) 
12/22

2
N

[ j 0 D( j )]  N  1 =
N 1

root
+1
N  i  1 nodes

p.212-213

= O(N log N)

§4 AVL Trees
Target : Speed up searching (with insertion and
deletion)

root

Tool : Binary search trees
small

large

Problem : Although Tp = O( height ), but the
height can be as bad as O( N ).

13/22

§4 AVL Trees

〖Example〗 3 binary search trees obtained for the months
of the year
Jan

Average search time = ?3.5

Feb

Mar

Apr

June
Aug

May

July

Sept

Dec

Oct

Entered from Jan to Dec

AST = 6.5

Nov

July
Feb

Aug
Apr

May

Jan
Dec

Mar
June

A balanced tree
14/22

What if the months
are entered in
alphabetical order?

Average search time = ?3.1
Oct

Nov

Sept

§4 AVL Trees

Adelson-Velskii-Landis (AVL) Trees (1962)
【Definition】An empty binary tree is height balanced. If T is a
nonempty binary tree with TL and TR as its left and right
subtrees, then T is height balanced iff
(1) TL and TR are height balanced, and
The height of an empty tree
(2) | hL  hR |  1 where hL and hisR defined
are thetoheights
be –1. of TL and TR ,
respectively.

【Definition】The balance factor BF( node ) = hL  hR . In an
AVL tree, BF( node ) = 1, 0, or 1.
4

3
2
1
15/22

5

5

2
6

1
7

8
4 7

3

7

2
1

8
4

3

5

§4 AVL Trees

〖Example〗 Input the months

Mar

May

1
2
0

Mar

Nov
1
2
01
0

1
0

May

Single rotation

May
0

00

00

Mar

Nov

Nov

 The trouble maker Nov is in the right subtree’s right
subtree of the trouble finder Mar. Hence it is called an
RR rotation.
A is not necessarily
In general:
the root of the tree
1

A

RR
0

16/22

1

BR

B
BL

0

RR

BR

B

A

Rotation

AL

AL
BL

A

Insertion

B

0

2

BR
AL

BL

Aug

§4 AVL Trees

Apr
2
1
01
12

1
2
01
1

LL

May
210

00

Mar

Nov

1
010

Rotation

May
00

Aug

Nov

10

0

0

Aug

Apr

Mar

0

Apr
In general:
1
0

2

LL

A

1

Insertion

B

A

17/22

BR

LL

B
AR
BL

B

Rotation

AR
BL

0

BR

0

A
BL
BR

AR

§4 AVL Trees

Jan

21
2
1
01

Double Rotation

1
2
01
0

May

1
010

00

Aug

1
010

Nov

0

10

Apr

Mar

Aug

LR

0

Jan

Mar

1
0

May

0

0

Apr

Jan

0

Nov

Rotation

In general:
1
0

B

A

CL

Insertion

1

B

0

C
BL

2

LR

A

BL

CL

18/22

0 or 1

C

1 or 0

B

AR
CR

OR

0

Rotation

1

C

AR
CR

LR

BL

A
CL

CR
OR

AR

Dec

July

§4 AVL Trees

Feb

1
2
01
21

Mar

1
2
10

Aug

1
0

May

0

01

Apr

Jan

1
0

Nov

Dec

10

01
10

Aug

Jan

1
0

May
0

Nov

0

0

Apr

Feb

July

2

RL

July
0

Mar

1
02
1
0

Rotation
0

0

Dec

1
2
01
1

RL

0

Feb
In general:
1

A
0

RL
0

Insertion

B

1

C

AL
CL

A

CR

CL

19/22

B

0 or 1

C

1 or 0

A
CR

OR

0

Rotation

C

AL
BR

1

BR
AL

B
CL

CR
OR

BR

June

Oct

§4 AVL Trees

Sept
1
0

1
0 2
1
01
21

Jan
Mar
Jan
1
1
12
1
0 1
00
02
1
0
1
1
12
1
0
0 1
Dec
Mar
May
Dec Dec
Mar

1 10

1 Aug
Aug

Aug

0 0

0 Apr
Apr

Apr

0

0

Feb
Feb0
Feb

01
10 1
1
Jan

July
July

1
00

0 July
June

June

2
10

1
0
May
Nov
Nov

1
0 1
0
Nov 0
Oct
May
0
0

June

Note: Several bf’s
might be changed even if
we don’t need to reconstruct
the tree.

Oct 0
Sept

Another option is to keep a height field for each node.

20/22

§4 AVL Trees
AvlTree Insert( ElementType X, AvlTree T )
{ if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct AvlNode ) );
if ( T == NULL ) FatalError( "Out of space!!!" );
else { T->Element = X; T->Height = 0; T->Left = T->Right = NULL; }
} /* End creating a one-node tree */
else if ( X < T->Element ) { /* handle left insertion */
T->Left = Insert( X, T->Left );
if ( Height( T->Left ) - Height( T->Right ) == 2 ) /* not balanced */
if ( X < T->Left->Element ) /* LL Rotation */
T = SingleRotateWithLeft( T );
else /* LR Rotation */
T = DoubleRotateWithLeft( T ); } /* End left */
else if( X > T->Element ) { /* handle right insertion */
T->Right = Insert( X, T->Right );
if ( Height( T->Right ) - Height( T->Left ) == 2 ) /* not balanced */
if ( X > T->Right->Element ) /* RR Rotation */
T = SingleRotateWithRight( T );
else /* RL Rotation */
T = DoubleRotateWithRight( T ); } /* End right */
/* Else X is in the tree already; we'll do nothing */
T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
return T;
}

Home work:

p.136 4.16
Create an AVL Tree
p.136 4.22
Double Rotation

21/22

§4 AVL Trees

Let nh be the minimum number of nodes in a height balanced tree of
height h. Then the tree must look like

A
h2

A
h1

last question:
OROne
h1
h2  nh = nh1 + nh2 + 1

Obviously we have Tp = O( h )
where h is the height of the tree.
But h = ?

Fibonacci numbers:
F0 = 0, F1 = 1, Fi = Fi1 + Fi2 for i > 1
 nh = Fh+2  1, for h  0
i


1  1 5 
Fibonacci number theory gives that Fi 


1  1  5 
 nh 
5  2 
22/22

5

h 2

1

 h  O(lnn)

2




Slide 8

§3 The Search Tree ADT -- Binary Search Trees
1. Definition
【Definition】A binary search tree is a binary tree. It may be
(1)
(2)
(3)
(4)

empty. If it is not empty, it satisfies the following properties:
Every node has a key which is an integer, and the keys are
distinct.
The keys in a nonempty left subtree must be smaller than
the key in the root of the subtree.
The keys in a nonempty right subtree must be larger than
the key in the root of the subtree.
The left and right subtrees are also binary search trees.

30

5
2

1/22

60

40

20
70

65

15
80

12

10

25
22

§3 Binary Search Trees

2. ADT
Objects: A finite ordered list with zero or more elements.
Operations:

 SearchTree MakeEmpty( SearchTree T );
 Position Find( ElementType X, SearchTree T );
 Position FindMin( SearchTree T );
 Position FindMax( SearchTree T );
 SearchTree Insert( ElementType X, SearchTree T );
 SearchTree Delete( ElementType X, SearchTree T );
 ElementType Retrieve( Position P );

2/22

§3 Binary Search Trees

3. Implementations

 Find

Must this test
be performed first?

Position Find( ElementType X, SearchTree T )
{
if ( T == NULL )
These are
return NULL; /* not found in an empty tree */
tail recursions.
if ( X < T->Element ) /* if smaller than root */
return Find( X, T->Left ); /* search left subtree */
else
if ( X > T->Element ) /* if larger than root */
return Find( X, T->Right ); /* search right subtree */
else /* if X == root */
return T; /* found */
}
T( N ) = S ( N ) = O( d ) where d is the depth of X

3/22

§3 Binary Search Trees

Position Iter_Find( ElementType X, SearchTree T )
{
/* iterative version of Find */
while ( T ) {
if ( X == T->Element )
return T ; /* found */
if ( X < T->Element )
T = T->Left ; /*move down along left path */
else
T = T-> Right ; /* move down along right path */
} /* end while-loop */
return NULL ; /* not found */
}

4/22



FindMin

§3 Binary Search Trees

Position FindMin( SearchTree T )
T( N ) = O ( d )
{
if ( T == NULL )
return NULL; /* not found in an empty tree */
else
if ( T->Left == NULL ) return T; /* found left most */
else return FindMin( T->Left ); /* keep moving to left */
}

 FindMax
Position FindMax( SearchTree T )
T( N ) = O ( d )
{
if ( T != NULL )
while ( T->Right != NULL )
T = T->Right; /* keep moving to find right most */
return T; /* return NULL or the right most */
}

5/22

§3 Binary Search Trees

 Insert
Sketch of the idea:
Insert 80

30
5
2

40
25 35

Insert 35

Insert 25

6/22

 check if 80 is already in the tree
 80 > 40, so it must be the right child
80

of 40

Thisifis35
theis last
nodein the tree
 check
already
we encounter
 35search
< 40, so it must be the left child of 40
when
for the key number.
It will be the parent
 check if 25 is already in the tree
of the new node.
 25 > 5, so it must be the right child of 5

§3 Binary Search Trees
SearchTree Insert( ElementType X, SearchTree T )
{
if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct TreeNode ) );
if ( T == NULL )
FatalError( "Out of space!!!" );
else {
T->Element = X;
How would you
T->Left = T->Right = NULL; }
Handle
T(
N ) = duplicated
O(d)
} /* End creating a one-node tree */
Keys?
else /* If there is a tree */
if ( X < T->Element )
T->Left = Insert( X, T->Left );
else
if ( X > T->Element )
T->Right = Insert( X, T->Right );
/* Else X is in the tree already; we'll do nothing */
return T; /* Do not forget this line!! */
}

7/22

§3 Binary Search Trees

 Delete

 Delete a leaf nodeNote:
: Reset
its kinds
parentoflink
to NULL.
These
nodes
have: degree
atthe
most
1. by its single child.
 Delete a degree 1 node
Replace
node
 Delete a degree 2 node :

 Replace the node by the largest one in its left subtree or
the smallest one in its right subtree.
 Delete the replacing node from the subtree.

〖Example〗 Delete 60

40
20

Solution 1: reset left subtree.

10

60
55
30

50 70

Solution 2: reset right subtree.

45

55
52
52

8/22

§3 Binary Search Trees
SearchTree Delete( ElementType X, SearchTree T )
{ Position TmpCell;
if ( T == NULL ) Error( "Element not found" );
else if ( X < T->Element ) /* Go left */
T->Left = Delete( X, T->Left );
else if ( X > T->Element ) /* Go right */
T->Right = Delete( X, T->Right );
else /* Found element to be deleted */
if ( T->Left && T->Right ) { /* Two children */
/* Replace with smallest in right subtree */
TmpCell = FindMin( T->Right );
T->Element = TmpCell->Element;
T->Right = Delete( T->Element, T->Right ); } /* End if */
else { /* One or zero child */
TmpCell = T;
if ( T->Left == NULL ) /* Also handles 0 child */
T = T->Right;
else if ( T->Right == NULL ) T = T->Left;
free( TmpCell ); } /* End else 1 or 0 child */
return T;
T( N ) = O ( h ) where h is the height of the tree
}
9/22

§3 Binary Search Trees

Note:
If there are not many deletions, then lazy deletion
may be employed: add a flag field to each node, to mark
if a node is active or is deleted. Therefore we can delete
a node without actually freeing the space of that node.
If a deleted key is reinserted, we won’t have to call
malloc again.

While the number of deleted nodes
is the same as the number of active nodes
in the tree, will it seriously affect
the efficiency of the operations?

10/22

§3 Binary Search Trees

4. Average-Case Analysis
Question: Place n elements in a binary search tree. How
high can this tree be?

Answer: The height depends on the order of insertion.
〖Example〗 Given elements 1, 2, 3, 4, 5, 6, 7. Insert
them into a binary search tree in the orders:
4, 2, 1, 3, 6, 5, 7
and
1, 2, 3, 4, 5, 6, 7
4
2
1

6
3

5

h=2

11/22

h=6
7

§3 Binary Search Trees

【Definition】The internal path length for a tree of N nodes
N

is defined to be:

D( N )   d ( i ) , D(1)  0
i 1

where d( i ) is the
depth of work:
node i.
Home

【Theorem】 Assume that all binary search trees are equally
p.139 4.42
likely. Then the average D(N) (taken over all possible
Isomorphic
Trees
insertion sequences)
is O(N log
N). Thus the expected
depth of any node is O(log N).

p.140 4.45
D( N ) = D( i ) + D( N  i  1 ) + N  1
Threaded Trees

Proof:
Since all subtree sizes are
equally likely, the average
i nodes
value of both D( i ) and
N 1
D( N  i  1 ) is [ j  0 D( j )] N .

D( N ) 
12/22

2
N

[ j 0 D( j )]  N  1 =
N 1

root
+1
N  i  1 nodes

p.212-213

= O(N log N)

§4 AVL Trees
Target : Speed up searching (with insertion and
deletion)

root

Tool : Binary search trees
small

large

Problem : Although Tp = O( height ), but the
height can be as bad as O( N ).

13/22

§4 AVL Trees

〖Example〗 3 binary search trees obtained for the months
of the year
Jan

Average search time = ?3.5

Feb

Mar

Apr

June
Aug

May

July

Sept

Dec

Oct

Entered from Jan to Dec

AST = 6.5

Nov

July
Feb

Aug
Apr

May

Jan
Dec

Mar
June

A balanced tree
14/22

What if the months
are entered in
alphabetical order?

Average search time = ?3.1
Oct

Nov

Sept

§4 AVL Trees

Adelson-Velskii-Landis (AVL) Trees (1962)
【Definition】An empty binary tree is height balanced. If T is a
nonempty binary tree with TL and TR as its left and right
subtrees, then T is height balanced iff
(1) TL and TR are height balanced, and
The height of an empty tree
(2) | hL  hR |  1 where hL and hisR defined
are thetoheights
be –1. of TL and TR ,
respectively.

【Definition】The balance factor BF( node ) = hL  hR . In an
AVL tree, BF( node ) = 1, 0, or 1.
4

3
2
1
15/22

5

5

2
6

1
7

8
4 7

3

7

2
1

8
4

3

5

§4 AVL Trees

〖Example〗 Input the months

Mar

May

1
2
0

Mar

Nov
1
2
01
0

1
0

May

Single rotation

May
0

00

00

Mar

Nov

Nov

 The trouble maker Nov is in the right subtree’s right
subtree of the trouble finder Mar. Hence it is called an
RR rotation.
A is not necessarily
In general:
the root of the tree
1

A

RR
0

16/22

1

BR

B
BL

0

RR

BR

B

A

Rotation

AL

AL
BL

A

Insertion

B

0

2

BR
AL

BL

Aug

§4 AVL Trees

Apr
2
1
01
12

1
2
01
1

LL

May
210

00

Mar

Nov

1
010

Rotation

May
00

Aug

Nov

10

0

0

Aug

Apr

Mar

0

Apr
In general:
1
0

2

LL

A

1

Insertion

B

A

17/22

BR

LL

B
AR
BL

B

Rotation

AR
BL

0

BR

0

A
BL
BR

AR

§4 AVL Trees

Jan

21
2
1
01

Double Rotation

1
2
01
0

May

1
010

00

Aug

1
010

Nov

0

10

Apr

Mar

Aug

LR

0

Jan

Mar

1
0

May

0

0

Apr

Jan

0

Nov

Rotation

In general:
1
0

B

A

CL

Insertion

1

B

0

C
BL

2

LR

A

BL

CL

18/22

0 or 1

C

1 or 0

B

AR
CR

OR

0

Rotation

1

C

AR
CR

LR

BL

A
CL

CR
OR

AR

Dec

July

§4 AVL Trees

Feb

1
2
01
21

Mar

1
2
10

Aug

1
0

May

0

01

Apr

Jan

1
0

Nov

Dec

10

01
10

Aug

Jan

1
0

May
0

Nov

0

0

Apr

Feb

July

2

RL

July
0

Mar

1
02
1
0

Rotation
0

0

Dec

1
2
01
1

RL

0

Feb
In general:
1

A
0

RL
0

Insertion

B

1

C

AL
CL

A

CR

CL

19/22

B

0 or 1

C

1 or 0

A
CR

OR

0

Rotation

C

AL
BR

1

BR
AL

B
CL

CR
OR

BR

June

Oct

§4 AVL Trees

Sept
1
0

1
0 2
1
01
21

Jan
Mar
Jan
1
1
12
1
0 1
00
02
1
0
1
1
12
1
0
0 1
Dec
Mar
May
Dec Dec
Mar

1 10

1 Aug
Aug

Aug

0 0

0 Apr
Apr

Apr

0

0

Feb
Feb0
Feb

01
10 1
1
Jan

July
July

1
00

0 July
June

June

2
10

1
0
May
Nov
Nov

1
0 1
0
Nov 0
Oct
May
0
0

June

Note: Several bf’s
might be changed even if
we don’t need to reconstruct
the tree.

Oct 0
Sept

Another option is to keep a height field for each node.

20/22

§4 AVL Trees
AvlTree Insert( ElementType X, AvlTree T )
{ if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct AvlNode ) );
if ( T == NULL ) FatalError( "Out of space!!!" );
else { T->Element = X; T->Height = 0; T->Left = T->Right = NULL; }
} /* End creating a one-node tree */
else if ( X < T->Element ) { /* handle left insertion */
T->Left = Insert( X, T->Left );
if ( Height( T->Left ) - Height( T->Right ) == 2 ) /* not balanced */
if ( X < T->Left->Element ) /* LL Rotation */
T = SingleRotateWithLeft( T );
else /* LR Rotation */
T = DoubleRotateWithLeft( T ); } /* End left */
else if( X > T->Element ) { /* handle right insertion */
T->Right = Insert( X, T->Right );
if ( Height( T->Right ) - Height( T->Left ) == 2 ) /* not balanced */
if ( X > T->Right->Element ) /* RR Rotation */
T = SingleRotateWithRight( T );
else /* RL Rotation */
T = DoubleRotateWithRight( T ); } /* End right */
/* Else X is in the tree already; we'll do nothing */
T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
return T;
}

Home work:

p.136 4.16
Create an AVL Tree
p.136 4.22
Double Rotation

21/22

§4 AVL Trees

Let nh be the minimum number of nodes in a height balanced tree of
height h. Then the tree must look like

A
h2

A
h1

last question:
OROne
h1
h2  nh = nh1 + nh2 + 1

Obviously we have Tp = O( h )
where h is the height of the tree.
But h = ?

Fibonacci numbers:
F0 = 0, F1 = 1, Fi = Fi1 + Fi2 for i > 1
 nh = Fh+2  1, for h  0
i


1  1 5 
Fibonacci number theory gives that Fi 


1  1  5 
 nh 
5  2 
22/22

5

h 2

1

 h  O(lnn)

2




Slide 9

§3 The Search Tree ADT -- Binary Search Trees
1. Definition
【Definition】A binary search tree is a binary tree. It may be
(1)
(2)
(3)
(4)

empty. If it is not empty, it satisfies the following properties:
Every node has a key which is an integer, and the keys are
distinct.
The keys in a nonempty left subtree must be smaller than
the key in the root of the subtree.
The keys in a nonempty right subtree must be larger than
the key in the root of the subtree.
The left and right subtrees are also binary search trees.

30

5
2

1/22

60

40

20
70

65

15
80

12

10

25
22

§3 Binary Search Trees

2. ADT
Objects: A finite ordered list with zero or more elements.
Operations:

 SearchTree MakeEmpty( SearchTree T );
 Position Find( ElementType X, SearchTree T );
 Position FindMin( SearchTree T );
 Position FindMax( SearchTree T );
 SearchTree Insert( ElementType X, SearchTree T );
 SearchTree Delete( ElementType X, SearchTree T );
 ElementType Retrieve( Position P );

2/22

§3 Binary Search Trees

3. Implementations

 Find

Must this test
be performed first?

Position Find( ElementType X, SearchTree T )
{
if ( T == NULL )
These are
return NULL; /* not found in an empty tree */
tail recursions.
if ( X < T->Element ) /* if smaller than root */
return Find( X, T->Left ); /* search left subtree */
else
if ( X > T->Element ) /* if larger than root */
return Find( X, T->Right ); /* search right subtree */
else /* if X == root */
return T; /* found */
}
T( N ) = S ( N ) = O( d ) where d is the depth of X

3/22

§3 Binary Search Trees

Position Iter_Find( ElementType X, SearchTree T )
{
/* iterative version of Find */
while ( T ) {
if ( X == T->Element )
return T ; /* found */
if ( X < T->Element )
T = T->Left ; /*move down along left path */
else
T = T-> Right ; /* move down along right path */
} /* end while-loop */
return NULL ; /* not found */
}

4/22



FindMin

§3 Binary Search Trees

Position FindMin( SearchTree T )
T( N ) = O ( d )
{
if ( T == NULL )
return NULL; /* not found in an empty tree */
else
if ( T->Left == NULL ) return T; /* found left most */
else return FindMin( T->Left ); /* keep moving to left */
}

 FindMax
Position FindMax( SearchTree T )
T( N ) = O ( d )
{
if ( T != NULL )
while ( T->Right != NULL )
T = T->Right; /* keep moving to find right most */
return T; /* return NULL or the right most */
}

5/22

§3 Binary Search Trees

 Insert
Sketch of the idea:
Insert 80

30
5
2

40
25 35

Insert 35

Insert 25

6/22

 check if 80 is already in the tree
 80 > 40, so it must be the right child
80

of 40

Thisifis35
theis last
nodein the tree
 check
already
we encounter
 35search
< 40, so it must be the left child of 40
when
for the key number.
It will be the parent
 check if 25 is already in the tree
of the new node.
 25 > 5, so it must be the right child of 5

§3 Binary Search Trees
SearchTree Insert( ElementType X, SearchTree T )
{
if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct TreeNode ) );
if ( T == NULL )
FatalError( "Out of space!!!" );
else {
T->Element = X;
How would you
T->Left = T->Right = NULL; }
Handle
T(
N ) = duplicated
O(d)
} /* End creating a one-node tree */
Keys?
else /* If there is a tree */
if ( X < T->Element )
T->Left = Insert( X, T->Left );
else
if ( X > T->Element )
T->Right = Insert( X, T->Right );
/* Else X is in the tree already; we'll do nothing */
return T; /* Do not forget this line!! */
}

7/22

§3 Binary Search Trees

 Delete

 Delete a leaf nodeNote:
: Reset
its kinds
parentoflink
to NULL.
These
nodes
have: degree
atthe
most
1. by its single child.
 Delete a degree 1 node
Replace
node
 Delete a degree 2 node :

 Replace the node by the largest one in its left subtree or
the smallest one in its right subtree.
 Delete the replacing node from the subtree.

〖Example〗 Delete 60

40
20

Solution 1: reset left subtree.

10

60
55
30

50 70

Solution 2: reset right subtree.

45

55
52
52

8/22

§3 Binary Search Trees
SearchTree Delete( ElementType X, SearchTree T )
{ Position TmpCell;
if ( T == NULL ) Error( "Element not found" );
else if ( X < T->Element ) /* Go left */
T->Left = Delete( X, T->Left );
else if ( X > T->Element ) /* Go right */
T->Right = Delete( X, T->Right );
else /* Found element to be deleted */
if ( T->Left && T->Right ) { /* Two children */
/* Replace with smallest in right subtree */
TmpCell = FindMin( T->Right );
T->Element = TmpCell->Element;
T->Right = Delete( T->Element, T->Right ); } /* End if */
else { /* One or zero child */
TmpCell = T;
if ( T->Left == NULL ) /* Also handles 0 child */
T = T->Right;
else if ( T->Right == NULL ) T = T->Left;
free( TmpCell ); } /* End else 1 or 0 child */
return T;
T( N ) = O ( h ) where h is the height of the tree
}
9/22

§3 Binary Search Trees

Note:
If there are not many deletions, then lazy deletion
may be employed: add a flag field to each node, to mark
if a node is active or is deleted. Therefore we can delete
a node without actually freeing the space of that node.
If a deleted key is reinserted, we won’t have to call
malloc again.

While the number of deleted nodes
is the same as the number of active nodes
in the tree, will it seriously affect
the efficiency of the operations?

10/22

§3 Binary Search Trees

4. Average-Case Analysis
Question: Place n elements in a binary search tree. How
high can this tree be?

Answer: The height depends on the order of insertion.
〖Example〗 Given elements 1, 2, 3, 4, 5, 6, 7. Insert
them into a binary search tree in the orders:
4, 2, 1, 3, 6, 5, 7
and
1, 2, 3, 4, 5, 6, 7
4
2
1

6
3

5

h=2

11/22

h=6
7

§3 Binary Search Trees

【Definition】The internal path length for a tree of N nodes
N

is defined to be:

D( N )   d ( i ) , D(1)  0
i 1

where d( i ) is the
depth of work:
node i.
Home

【Theorem】 Assume that all binary search trees are equally
p.139 4.42
likely. Then the average D(N) (taken over all possible
Isomorphic
Trees
insertion sequences)
is O(N log
N). Thus the expected
depth of any node is O(log N).

p.140 4.45
D( N ) = D( i ) + D( N  i  1 ) + N  1
Threaded Trees

Proof:
Since all subtree sizes are
equally likely, the average
i nodes
value of both D( i ) and
N 1
D( N  i  1 ) is [ j  0 D( j )] N .

D( N ) 
12/22

2
N

[ j 0 D( j )]  N  1 =
N 1

root
+1
N  i  1 nodes

p.212-213

= O(N log N)

§4 AVL Trees
Target : Speed up searching (with insertion and
deletion)

root

Tool : Binary search trees
small

large

Problem : Although Tp = O( height ), but the
height can be as bad as O( N ).

13/22

§4 AVL Trees

〖Example〗 3 binary search trees obtained for the months
of the year
Jan

Average search time = ?3.5

Feb

Mar

Apr

June
Aug

May

July

Sept

Dec

Oct

Entered from Jan to Dec

AST = 6.5

Nov

July
Feb

Aug
Apr

May

Jan
Dec

Mar
June

A balanced tree
14/22

What if the months
are entered in
alphabetical order?

Average search time = ?3.1
Oct

Nov

Sept

§4 AVL Trees

Adelson-Velskii-Landis (AVL) Trees (1962)
【Definition】An empty binary tree is height balanced. If T is a
nonempty binary tree with TL and TR as its left and right
subtrees, then T is height balanced iff
(1) TL and TR are height balanced, and
The height of an empty tree
(2) | hL  hR |  1 where hL and hisR defined
are thetoheights
be –1. of TL and TR ,
respectively.

【Definition】The balance factor BF( node ) = hL  hR . In an
AVL tree, BF( node ) = 1, 0, or 1.
4

3
2
1
15/22

5

5

2
6

1
7

8
4 7

3

7

2
1

8
4

3

5

§4 AVL Trees

〖Example〗 Input the months

Mar

May

1
2
0

Mar

Nov
1
2
01
0

1
0

May

Single rotation

May
0

00

00

Mar

Nov

Nov

 The trouble maker Nov is in the right subtree’s right
subtree of the trouble finder Mar. Hence it is called an
RR rotation.
A is not necessarily
In general:
the root of the tree
1

A

RR
0

16/22

1

BR

B
BL

0

RR

BR

B

A

Rotation

AL

AL
BL

A

Insertion

B

0

2

BR
AL

BL

Aug

§4 AVL Trees

Apr
2
1
01
12

1
2
01
1

LL

May
210

00

Mar

Nov

1
010

Rotation

May
00

Aug

Nov

10

0

0

Aug

Apr

Mar

0

Apr
In general:
1
0

2

LL

A

1

Insertion

B

A

17/22

BR

LL

B
AR
BL

B

Rotation

AR
BL

0

BR

0

A
BL
BR

AR

§4 AVL Trees

Jan

21
2
1
01

Double Rotation

1
2
01
0

May

1
010

00

Aug

1
010

Nov

0

10

Apr

Mar

Aug

LR

0

Jan

Mar

1
0

May

0

0

Apr

Jan

0

Nov

Rotation

In general:
1
0

B

A

CL

Insertion

1

B

0

C
BL

2

LR

A

BL

CL

18/22

0 or 1

C

1 or 0

B

AR
CR

OR

0

Rotation

1

C

AR
CR

LR

BL

A
CL

CR
OR

AR

Dec

July

§4 AVL Trees

Feb

1
2
01
21

Mar

1
2
10

Aug

1
0

May

0

01

Apr

Jan

1
0

Nov

Dec

10

01
10

Aug

Jan

1
0

May
0

Nov

0

0

Apr

Feb

July

2

RL

July
0

Mar

1
02
1
0

Rotation
0

0

Dec

1
2
01
1

RL

0

Feb
In general:
1

A
0

RL
0

Insertion

B

1

C

AL
CL

A

CR

CL

19/22

B

0 or 1

C

1 or 0

A
CR

OR

0

Rotation

C

AL
BR

1

BR
AL

B
CL

CR
OR

BR

June

Oct

§4 AVL Trees

Sept
1
0

1
0 2
1
01
21

Jan
Mar
Jan
1
1
12
1
0 1
00
02
1
0
1
1
12
1
0
0 1
Dec
Mar
May
Dec Dec
Mar

1 10

1 Aug
Aug

Aug

0 0

0 Apr
Apr

Apr

0

0

Feb
Feb0
Feb

01
10 1
1
Jan

July
July

1
00

0 July
June

June

2
10

1
0
May
Nov
Nov

1
0 1
0
Nov 0
Oct
May
0
0

June

Note: Several bf’s
might be changed even if
we don’t need to reconstruct
the tree.

Oct 0
Sept

Another option is to keep a height field for each node.

20/22

§4 AVL Trees
AvlTree Insert( ElementType X, AvlTree T )
{ if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct AvlNode ) );
if ( T == NULL ) FatalError( "Out of space!!!" );
else { T->Element = X; T->Height = 0; T->Left = T->Right = NULL; }
} /* End creating a one-node tree */
else if ( X < T->Element ) { /* handle left insertion */
T->Left = Insert( X, T->Left );
if ( Height( T->Left ) - Height( T->Right ) == 2 ) /* not balanced */
if ( X < T->Left->Element ) /* LL Rotation */
T = SingleRotateWithLeft( T );
else /* LR Rotation */
T = DoubleRotateWithLeft( T ); } /* End left */
else if( X > T->Element ) { /* handle right insertion */
T->Right = Insert( X, T->Right );
if ( Height( T->Right ) - Height( T->Left ) == 2 ) /* not balanced */
if ( X > T->Right->Element ) /* RR Rotation */
T = SingleRotateWithRight( T );
else /* RL Rotation */
T = DoubleRotateWithRight( T ); } /* End right */
/* Else X is in the tree already; we'll do nothing */
T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
return T;
}

Home work:

p.136 4.16
Create an AVL Tree
p.136 4.22
Double Rotation

21/22

§4 AVL Trees

Let nh be the minimum number of nodes in a height balanced tree of
height h. Then the tree must look like

A
h2

A
h1

last question:
OROne
h1
h2  nh = nh1 + nh2 + 1

Obviously we have Tp = O( h )
where h is the height of the tree.
But h = ?

Fibonacci numbers:
F0 = 0, F1 = 1, Fi = Fi1 + Fi2 for i > 1
 nh = Fh+2  1, for h  0
i


1  1 5 
Fibonacci number theory gives that Fi 


1  1  5 
 nh 
5  2 
22/22

5

h 2

1

 h  O(lnn)

2




Slide 10

§3 The Search Tree ADT -- Binary Search Trees
1. Definition
【Definition】A binary search tree is a binary tree. It may be
(1)
(2)
(3)
(4)

empty. If it is not empty, it satisfies the following properties:
Every node has a key which is an integer, and the keys are
distinct.
The keys in a nonempty left subtree must be smaller than
the key in the root of the subtree.
The keys in a nonempty right subtree must be larger than
the key in the root of the subtree.
The left and right subtrees are also binary search trees.

30

5
2

1/22

60

40

20
70

65

15
80

12

10

25
22

§3 Binary Search Trees

2. ADT
Objects: A finite ordered list with zero or more elements.
Operations:

 SearchTree MakeEmpty( SearchTree T );
 Position Find( ElementType X, SearchTree T );
 Position FindMin( SearchTree T );
 Position FindMax( SearchTree T );
 SearchTree Insert( ElementType X, SearchTree T );
 SearchTree Delete( ElementType X, SearchTree T );
 ElementType Retrieve( Position P );

2/22

§3 Binary Search Trees

3. Implementations

 Find

Must this test
be performed first?

Position Find( ElementType X, SearchTree T )
{
if ( T == NULL )
These are
return NULL; /* not found in an empty tree */
tail recursions.
if ( X < T->Element ) /* if smaller than root */
return Find( X, T->Left ); /* search left subtree */
else
if ( X > T->Element ) /* if larger than root */
return Find( X, T->Right ); /* search right subtree */
else /* if X == root */
return T; /* found */
}
T( N ) = S ( N ) = O( d ) where d is the depth of X

3/22

§3 Binary Search Trees

Position Iter_Find( ElementType X, SearchTree T )
{
/* iterative version of Find */
while ( T ) {
if ( X == T->Element )
return T ; /* found */
if ( X < T->Element )
T = T->Left ; /*move down along left path */
else
T = T-> Right ; /* move down along right path */
} /* end while-loop */
return NULL ; /* not found */
}

4/22



FindMin

§3 Binary Search Trees

Position FindMin( SearchTree T )
T( N ) = O ( d )
{
if ( T == NULL )
return NULL; /* not found in an empty tree */
else
if ( T->Left == NULL ) return T; /* found left most */
else return FindMin( T->Left ); /* keep moving to left */
}

 FindMax
Position FindMax( SearchTree T )
T( N ) = O ( d )
{
if ( T != NULL )
while ( T->Right != NULL )
T = T->Right; /* keep moving to find right most */
return T; /* return NULL or the right most */
}

5/22

§3 Binary Search Trees

 Insert
Sketch of the idea:
Insert 80

30
5
2

40
25 35

Insert 35

Insert 25

6/22

 check if 80 is already in the tree
 80 > 40, so it must be the right child
80

of 40

Thisifis35
theis last
nodein the tree
 check
already
we encounter
 35search
< 40, so it must be the left child of 40
when
for the key number.
It will be the parent
 check if 25 is already in the tree
of the new node.
 25 > 5, so it must be the right child of 5

§3 Binary Search Trees
SearchTree Insert( ElementType X, SearchTree T )
{
if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct TreeNode ) );
if ( T == NULL )
FatalError( "Out of space!!!" );
else {
T->Element = X;
How would you
T->Left = T->Right = NULL; }
Handle
T(
N ) = duplicated
O(d)
} /* End creating a one-node tree */
Keys?
else /* If there is a tree */
if ( X < T->Element )
T->Left = Insert( X, T->Left );
else
if ( X > T->Element )
T->Right = Insert( X, T->Right );
/* Else X is in the tree already; we'll do nothing */
return T; /* Do not forget this line!! */
}

7/22

§3 Binary Search Trees

 Delete

 Delete a leaf nodeNote:
: Reset
its kinds
parentoflink
to NULL.
These
nodes
have: degree
atthe
most
1. by its single child.
 Delete a degree 1 node
Replace
node
 Delete a degree 2 node :

 Replace the node by the largest one in its left subtree or
the smallest one in its right subtree.
 Delete the replacing node from the subtree.

〖Example〗 Delete 60

40
20

Solution 1: reset left subtree.

10

60
55
30

50 70

Solution 2: reset right subtree.

45

55
52
52

8/22

§3 Binary Search Trees
SearchTree Delete( ElementType X, SearchTree T )
{ Position TmpCell;
if ( T == NULL ) Error( "Element not found" );
else if ( X < T->Element ) /* Go left */
T->Left = Delete( X, T->Left );
else if ( X > T->Element ) /* Go right */
T->Right = Delete( X, T->Right );
else /* Found element to be deleted */
if ( T->Left && T->Right ) { /* Two children */
/* Replace with smallest in right subtree */
TmpCell = FindMin( T->Right );
T->Element = TmpCell->Element;
T->Right = Delete( T->Element, T->Right ); } /* End if */
else { /* One or zero child */
TmpCell = T;
if ( T->Left == NULL ) /* Also handles 0 child */
T = T->Right;
else if ( T->Right == NULL ) T = T->Left;
free( TmpCell ); } /* End else 1 or 0 child */
return T;
T( N ) = O ( h ) where h is the height of the tree
}
9/22

§3 Binary Search Trees

Note:
If there are not many deletions, then lazy deletion
may be employed: add a flag field to each node, to mark
if a node is active or is deleted. Therefore we can delete
a node without actually freeing the space of that node.
If a deleted key is reinserted, we won’t have to call
malloc again.

While the number of deleted nodes
is the same as the number of active nodes
in the tree, will it seriously affect
the efficiency of the operations?

10/22

§3 Binary Search Trees

4. Average-Case Analysis
Question: Place n elements in a binary search tree. How
high can this tree be?

Answer: The height depends on the order of insertion.
〖Example〗 Given elements 1, 2, 3, 4, 5, 6, 7. Insert
them into a binary search tree in the orders:
4, 2, 1, 3, 6, 5, 7
and
1, 2, 3, 4, 5, 6, 7
4
2
1

6
3

5

h=2

11/22

h=6
7

§3 Binary Search Trees

【Definition】The internal path length for a tree of N nodes
N

is defined to be:

D( N )   d ( i ) , D(1)  0
i 1

where d( i ) is the
depth of work:
node i.
Home

【Theorem】 Assume that all binary search trees are equally
p.139 4.42
likely. Then the average D(N) (taken over all possible
Isomorphic
Trees
insertion sequences)
is O(N log
N). Thus the expected
depth of any node is O(log N).

p.140 4.45
D( N ) = D( i ) + D( N  i  1 ) + N  1
Threaded Trees

Proof:
Since all subtree sizes are
equally likely, the average
i nodes
value of both D( i ) and
N 1
D( N  i  1 ) is [ j  0 D( j )] N .

D( N ) 
12/22

2
N

[ j 0 D( j )]  N  1 =
N 1

root
+1
N  i  1 nodes

p.212-213

= O(N log N)

§4 AVL Trees
Target : Speed up searching (with insertion and
deletion)

root

Tool : Binary search trees
small

large

Problem : Although Tp = O( height ), but the
height can be as bad as O( N ).

13/22

§4 AVL Trees

〖Example〗 3 binary search trees obtained for the months
of the year
Jan

Average search time = ?3.5

Feb

Mar

Apr

June
Aug

May

July

Sept

Dec

Oct

Entered from Jan to Dec

AST = 6.5

Nov

July
Feb

Aug
Apr

May

Jan
Dec

Mar
June

A balanced tree
14/22

What if the months
are entered in
alphabetical order?

Average search time = ?3.1
Oct

Nov

Sept

§4 AVL Trees

Adelson-Velskii-Landis (AVL) Trees (1962)
【Definition】An empty binary tree is height balanced. If T is a
nonempty binary tree with TL and TR as its left and right
subtrees, then T is height balanced iff
(1) TL and TR are height balanced, and
The height of an empty tree
(2) | hL  hR |  1 where hL and hisR defined
are thetoheights
be –1. of TL and TR ,
respectively.

【Definition】The balance factor BF( node ) = hL  hR . In an
AVL tree, BF( node ) = 1, 0, or 1.
4

3
2
1
15/22

5

5

2
6

1
7

8
4 7

3

7

2
1

8
4

3

5

§4 AVL Trees

〖Example〗 Input the months

Mar

May

1
2
0

Mar

Nov
1
2
01
0

1
0

May

Single rotation

May
0

00

00

Mar

Nov

Nov

 The trouble maker Nov is in the right subtree’s right
subtree of the trouble finder Mar. Hence it is called an
RR rotation.
A is not necessarily
In general:
the root of the tree
1

A

RR
0

16/22

1

BR

B
BL

0

RR

BR

B

A

Rotation

AL

AL
BL

A

Insertion

B

0

2

BR
AL

BL

Aug

§4 AVL Trees

Apr
2
1
01
12

1
2
01
1

LL

May
210

00

Mar

Nov

1
010

Rotation

May
00

Aug

Nov

10

0

0

Aug

Apr

Mar

0

Apr
In general:
1
0

2

LL

A

1

Insertion

B

A

17/22

BR

LL

B
AR
BL

B

Rotation

AR
BL

0

BR

0

A
BL
BR

AR

§4 AVL Trees

Jan

21
2
1
01

Double Rotation

1
2
01
0

May

1
010

00

Aug

1
010

Nov

0

10

Apr

Mar

Aug

LR

0

Jan

Mar

1
0

May

0

0

Apr

Jan

0

Nov

Rotation

In general:
1
0

B

A

CL

Insertion

1

B

0

C
BL

2

LR

A

BL

CL

18/22

0 or 1

C

1 or 0

B

AR
CR

OR

0

Rotation

1

C

AR
CR

LR

BL

A
CL

CR
OR

AR

Dec

July

§4 AVL Trees

Feb

1
2
01
21

Mar

1
2
10

Aug

1
0

May

0

01

Apr

Jan

1
0

Nov

Dec

10

01
10

Aug

Jan

1
0

May
0

Nov

0

0

Apr

Feb

July

2

RL

July
0

Mar

1
02
1
0

Rotation
0

0

Dec

1
2
01
1

RL

0

Feb
In general:
1

A
0

RL
0

Insertion

B

1

C

AL
CL

A

CR

CL

19/22

B

0 or 1

C

1 or 0

A
CR

OR

0

Rotation

C

AL
BR

1

BR
AL

B
CL

CR
OR

BR

June

Oct

§4 AVL Trees

Sept
1
0

1
0 2
1
01
21

Jan
Mar
Jan
1
1
12
1
0 1
00
02
1
0
1
1
12
1
0
0 1
Dec
Mar
May
Dec Dec
Mar

1 10

1 Aug
Aug

Aug

0 0

0 Apr
Apr

Apr

0

0

Feb
Feb0
Feb

01
10 1
1
Jan

July
July

1
00

0 July
June

June

2
10

1
0
May
Nov
Nov

1
0 1
0
Nov 0
Oct
May
0
0

June

Note: Several bf’s
might be changed even if
we don’t need to reconstruct
the tree.

Oct 0
Sept

Another option is to keep a height field for each node.

20/22

§4 AVL Trees
AvlTree Insert( ElementType X, AvlTree T )
{ if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct AvlNode ) );
if ( T == NULL ) FatalError( "Out of space!!!" );
else { T->Element = X; T->Height = 0; T->Left = T->Right = NULL; }
} /* End creating a one-node tree */
else if ( X < T->Element ) { /* handle left insertion */
T->Left = Insert( X, T->Left );
if ( Height( T->Left ) - Height( T->Right ) == 2 ) /* not balanced */
if ( X < T->Left->Element ) /* LL Rotation */
T = SingleRotateWithLeft( T );
else /* LR Rotation */
T = DoubleRotateWithLeft( T ); } /* End left */
else if( X > T->Element ) { /* handle right insertion */
T->Right = Insert( X, T->Right );
if ( Height( T->Right ) - Height( T->Left ) == 2 ) /* not balanced */
if ( X > T->Right->Element ) /* RR Rotation */
T = SingleRotateWithRight( T );
else /* RL Rotation */
T = DoubleRotateWithRight( T ); } /* End right */
/* Else X is in the tree already; we'll do nothing */
T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
return T;
}

Home work:

p.136 4.16
Create an AVL Tree
p.136 4.22
Double Rotation

21/22

§4 AVL Trees

Let nh be the minimum number of nodes in a height balanced tree of
height h. Then the tree must look like

A
h2

A
h1

last question:
OROne
h1
h2  nh = nh1 + nh2 + 1

Obviously we have Tp = O( h )
where h is the height of the tree.
But h = ?

Fibonacci numbers:
F0 = 0, F1 = 1, Fi = Fi1 + Fi2 for i > 1
 nh = Fh+2  1, for h  0
i


1  1 5 
Fibonacci number theory gives that Fi 


1  1  5 
 nh 
5  2 
22/22

5

h 2

1

 h  O(lnn)

2




Slide 11

§3 The Search Tree ADT -- Binary Search Trees
1. Definition
【Definition】A binary search tree is a binary tree. It may be
(1)
(2)
(3)
(4)

empty. If it is not empty, it satisfies the following properties:
Every node has a key which is an integer, and the keys are
distinct.
The keys in a nonempty left subtree must be smaller than
the key in the root of the subtree.
The keys in a nonempty right subtree must be larger than
the key in the root of the subtree.
The left and right subtrees are also binary search trees.

30

5
2

1/22

60

40

20
70

65

15
80

12

10

25
22

§3 Binary Search Trees

2. ADT
Objects: A finite ordered list with zero or more elements.
Operations:

 SearchTree MakeEmpty( SearchTree T );
 Position Find( ElementType X, SearchTree T );
 Position FindMin( SearchTree T );
 Position FindMax( SearchTree T );
 SearchTree Insert( ElementType X, SearchTree T );
 SearchTree Delete( ElementType X, SearchTree T );
 ElementType Retrieve( Position P );

2/22

§3 Binary Search Trees

3. Implementations

 Find

Must this test
be performed first?

Position Find( ElementType X, SearchTree T )
{
if ( T == NULL )
These are
return NULL; /* not found in an empty tree */
tail recursions.
if ( X < T->Element ) /* if smaller than root */
return Find( X, T->Left ); /* search left subtree */
else
if ( X > T->Element ) /* if larger than root */
return Find( X, T->Right ); /* search right subtree */
else /* if X == root */
return T; /* found */
}
T( N ) = S ( N ) = O( d ) where d is the depth of X

3/22

§3 Binary Search Trees

Position Iter_Find( ElementType X, SearchTree T )
{
/* iterative version of Find */
while ( T ) {
if ( X == T->Element )
return T ; /* found */
if ( X < T->Element )
T = T->Left ; /*move down along left path */
else
T = T-> Right ; /* move down along right path */
} /* end while-loop */
return NULL ; /* not found */
}

4/22



FindMin

§3 Binary Search Trees

Position FindMin( SearchTree T )
T( N ) = O ( d )
{
if ( T == NULL )
return NULL; /* not found in an empty tree */
else
if ( T->Left == NULL ) return T; /* found left most */
else return FindMin( T->Left ); /* keep moving to left */
}

 FindMax
Position FindMax( SearchTree T )
T( N ) = O ( d )
{
if ( T != NULL )
while ( T->Right != NULL )
T = T->Right; /* keep moving to find right most */
return T; /* return NULL or the right most */
}

5/22

§3 Binary Search Trees

 Insert
Sketch of the idea:
Insert 80

30
5
2

40
25 35

Insert 35

Insert 25

6/22

 check if 80 is already in the tree
 80 > 40, so it must be the right child
80

of 40

Thisifis35
theis last
nodein the tree
 check
already
we encounter
 35search
< 40, so it must be the left child of 40
when
for the key number.
It will be the parent
 check if 25 is already in the tree
of the new node.
 25 > 5, so it must be the right child of 5

§3 Binary Search Trees
SearchTree Insert( ElementType X, SearchTree T )
{
if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct TreeNode ) );
if ( T == NULL )
FatalError( "Out of space!!!" );
else {
T->Element = X;
How would you
T->Left = T->Right = NULL; }
Handle
T(
N ) = duplicated
O(d)
} /* End creating a one-node tree */
Keys?
else /* If there is a tree */
if ( X < T->Element )
T->Left = Insert( X, T->Left );
else
if ( X > T->Element )
T->Right = Insert( X, T->Right );
/* Else X is in the tree already; we'll do nothing */
return T; /* Do not forget this line!! */
}

7/22

§3 Binary Search Trees

 Delete

 Delete a leaf nodeNote:
: Reset
its kinds
parentoflink
to NULL.
These
nodes
have: degree
atthe
most
1. by its single child.
 Delete a degree 1 node
Replace
node
 Delete a degree 2 node :

 Replace the node by the largest one in its left subtree or
the smallest one in its right subtree.
 Delete the replacing node from the subtree.

〖Example〗 Delete 60

40
20

Solution 1: reset left subtree.

10

60
55
30

50 70

Solution 2: reset right subtree.

45

55
52
52

8/22

§3 Binary Search Trees
SearchTree Delete( ElementType X, SearchTree T )
{ Position TmpCell;
if ( T == NULL ) Error( "Element not found" );
else if ( X < T->Element ) /* Go left */
T->Left = Delete( X, T->Left );
else if ( X > T->Element ) /* Go right */
T->Right = Delete( X, T->Right );
else /* Found element to be deleted */
if ( T->Left && T->Right ) { /* Two children */
/* Replace with smallest in right subtree */
TmpCell = FindMin( T->Right );
T->Element = TmpCell->Element;
T->Right = Delete( T->Element, T->Right ); } /* End if */
else { /* One or zero child */
TmpCell = T;
if ( T->Left == NULL ) /* Also handles 0 child */
T = T->Right;
else if ( T->Right == NULL ) T = T->Left;
free( TmpCell ); } /* End else 1 or 0 child */
return T;
T( N ) = O ( h ) where h is the height of the tree
}
9/22

§3 Binary Search Trees

Note:
If there are not many deletions, then lazy deletion
may be employed: add a flag field to each node, to mark
if a node is active or is deleted. Therefore we can delete
a node without actually freeing the space of that node.
If a deleted key is reinserted, we won’t have to call
malloc again.

While the number of deleted nodes
is the same as the number of active nodes
in the tree, will it seriously affect
the efficiency of the operations?

10/22

§3 Binary Search Trees

4. Average-Case Analysis
Question: Place n elements in a binary search tree. How
high can this tree be?

Answer: The height depends on the order of insertion.
〖Example〗 Given elements 1, 2, 3, 4, 5, 6, 7. Insert
them into a binary search tree in the orders:
4, 2, 1, 3, 6, 5, 7
and
1, 2, 3, 4, 5, 6, 7
4
2
1

6
3

5

h=2

11/22

h=6
7

§3 Binary Search Trees

【Definition】The internal path length for a tree of N nodes
N

is defined to be:

D( N )   d ( i ) , D(1)  0
i 1

where d( i ) is the
depth of work:
node i.
Home

【Theorem】 Assume that all binary search trees are equally
p.139 4.42
likely. Then the average D(N) (taken over all possible
Isomorphic
Trees
insertion sequences)
is O(N log
N). Thus the expected
depth of any node is O(log N).

p.140 4.45
D( N ) = D( i ) + D( N  i  1 ) + N  1
Threaded Trees

Proof:
Since all subtree sizes are
equally likely, the average
i nodes
value of both D( i ) and
N 1
D( N  i  1 ) is [ j  0 D( j )] N .

D( N ) 
12/22

2
N

[ j 0 D( j )]  N  1 =
N 1

root
+1
N  i  1 nodes

p.212-213

= O(N log N)

§4 AVL Trees
Target : Speed up searching (with insertion and
deletion)

root

Tool : Binary search trees
small

large

Problem : Although Tp = O( height ), but the
height can be as bad as O( N ).

13/22

§4 AVL Trees

〖Example〗 3 binary search trees obtained for the months
of the year
Jan

Average search time = ?3.5

Feb

Mar

Apr

June
Aug

May

July

Sept

Dec

Oct

Entered from Jan to Dec

AST = 6.5

Nov

July
Feb

Aug
Apr

May

Jan
Dec

Mar
June

A balanced tree
14/22

What if the months
are entered in
alphabetical order?

Average search time = ?3.1
Oct

Nov

Sept

§4 AVL Trees

Adelson-Velskii-Landis (AVL) Trees (1962)
【Definition】An empty binary tree is height balanced. If T is a
nonempty binary tree with TL and TR as its left and right
subtrees, then T is height balanced iff
(1) TL and TR are height balanced, and
The height of an empty tree
(2) | hL  hR |  1 where hL and hisR defined
are thetoheights
be –1. of TL and TR ,
respectively.

【Definition】The balance factor BF( node ) = hL  hR . In an
AVL tree, BF( node ) = 1, 0, or 1.
4

3
2
1
15/22

5

5

2
6

1
7

8
4 7

3

7

2
1

8
4

3

5

§4 AVL Trees

〖Example〗 Input the months

Mar

May

1
2
0

Mar

Nov
1
2
01
0

1
0

May

Single rotation

May
0

00

00

Mar

Nov

Nov

 The trouble maker Nov is in the right subtree’s right
subtree of the trouble finder Mar. Hence it is called an
RR rotation.
A is not necessarily
In general:
the root of the tree
1

A

RR
0

16/22

1

BR

B
BL

0

RR

BR

B

A

Rotation

AL

AL
BL

A

Insertion

B

0

2

BR
AL

BL

Aug

§4 AVL Trees

Apr
2
1
01
12

1
2
01
1

LL

May
210

00

Mar

Nov

1
010

Rotation

May
00

Aug

Nov

10

0

0

Aug

Apr

Mar

0

Apr
In general:
1
0

2

LL

A

1

Insertion

B

A

17/22

BR

LL

B
AR
BL

B

Rotation

AR
BL

0

BR

0

A
BL
BR

AR

§4 AVL Trees

Jan

21
2
1
01

Double Rotation

1
2
01
0

May

1
010

00

Aug

1
010

Nov

0

10

Apr

Mar

Aug

LR

0

Jan

Mar

1
0

May

0

0

Apr

Jan

0

Nov

Rotation

In general:
1
0

B

A

CL

Insertion

1

B

0

C
BL

2

LR

A

BL

CL

18/22

0 or 1

C

1 or 0

B

AR
CR

OR

0

Rotation

1

C

AR
CR

LR

BL

A
CL

CR
OR

AR

Dec

July

§4 AVL Trees

Feb

1
2
01
21

Mar

1
2
10

Aug

1
0

May

0

01

Apr

Jan

1
0

Nov

Dec

10

01
10

Aug

Jan

1
0

May
0

Nov

0

0

Apr

Feb

July

2

RL

July
0

Mar

1
02
1
0

Rotation
0

0

Dec

1
2
01
1

RL

0

Feb
In general:
1

A
0

RL
0

Insertion

B

1

C

AL
CL

A

CR

CL

19/22

B

0 or 1

C

1 or 0

A
CR

OR

0

Rotation

C

AL
BR

1

BR
AL

B
CL

CR
OR

BR

June

Oct

§4 AVL Trees

Sept
1
0

1
0 2
1
01
21

Jan
Mar
Jan
1
1
12
1
0 1
00
02
1
0
1
1
12
1
0
0 1
Dec
Mar
May
Dec Dec
Mar

1 10

1 Aug
Aug

Aug

0 0

0 Apr
Apr

Apr

0

0

Feb
Feb0
Feb

01
10 1
1
Jan

July
July

1
00

0 July
June

June

2
10

1
0
May
Nov
Nov

1
0 1
0
Nov 0
Oct
May
0
0

June

Note: Several bf’s
might be changed even if
we don’t need to reconstruct
the tree.

Oct 0
Sept

Another option is to keep a height field for each node.

20/22

§4 AVL Trees
AvlTree Insert( ElementType X, AvlTree T )
{ if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct AvlNode ) );
if ( T == NULL ) FatalError( "Out of space!!!" );
else { T->Element = X; T->Height = 0; T->Left = T->Right = NULL; }
} /* End creating a one-node tree */
else if ( X < T->Element ) { /* handle left insertion */
T->Left = Insert( X, T->Left );
if ( Height( T->Left ) - Height( T->Right ) == 2 ) /* not balanced */
if ( X < T->Left->Element ) /* LL Rotation */
T = SingleRotateWithLeft( T );
else /* LR Rotation */
T = DoubleRotateWithLeft( T ); } /* End left */
else if( X > T->Element ) { /* handle right insertion */
T->Right = Insert( X, T->Right );
if ( Height( T->Right ) - Height( T->Left ) == 2 ) /* not balanced */
if ( X > T->Right->Element ) /* RR Rotation */
T = SingleRotateWithRight( T );
else /* RL Rotation */
T = DoubleRotateWithRight( T ); } /* End right */
/* Else X is in the tree already; we'll do nothing */
T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
return T;
}

Home work:

p.136 4.16
Create an AVL Tree
p.136 4.22
Double Rotation

21/22

§4 AVL Trees

Let nh be the minimum number of nodes in a height balanced tree of
height h. Then the tree must look like

A
h2

A
h1

last question:
OROne
h1
h2  nh = nh1 + nh2 + 1

Obviously we have Tp = O( h )
where h is the height of the tree.
But h = ?

Fibonacci numbers:
F0 = 0, F1 = 1, Fi = Fi1 + Fi2 for i > 1
 nh = Fh+2  1, for h  0
i


1  1 5 
Fibonacci number theory gives that Fi 


1  1  5 
 nh 
5  2 
22/22

5

h 2

1

 h  O(lnn)

2




Slide 12

§3 The Search Tree ADT -- Binary Search Trees
1. Definition
【Definition】A binary search tree is a binary tree. It may be
(1)
(2)
(3)
(4)

empty. If it is not empty, it satisfies the following properties:
Every node has a key which is an integer, and the keys are
distinct.
The keys in a nonempty left subtree must be smaller than
the key in the root of the subtree.
The keys in a nonempty right subtree must be larger than
the key in the root of the subtree.
The left and right subtrees are also binary search trees.

30

5
2

1/22

60

40

20
70

65

15
80

12

10

25
22

§3 Binary Search Trees

2. ADT
Objects: A finite ordered list with zero or more elements.
Operations:

 SearchTree MakeEmpty( SearchTree T );
 Position Find( ElementType X, SearchTree T );
 Position FindMin( SearchTree T );
 Position FindMax( SearchTree T );
 SearchTree Insert( ElementType X, SearchTree T );
 SearchTree Delete( ElementType X, SearchTree T );
 ElementType Retrieve( Position P );

2/22

§3 Binary Search Trees

3. Implementations

 Find

Must this test
be performed first?

Position Find( ElementType X, SearchTree T )
{
if ( T == NULL )
These are
return NULL; /* not found in an empty tree */
tail recursions.
if ( X < T->Element ) /* if smaller than root */
return Find( X, T->Left ); /* search left subtree */
else
if ( X > T->Element ) /* if larger than root */
return Find( X, T->Right ); /* search right subtree */
else /* if X == root */
return T; /* found */
}
T( N ) = S ( N ) = O( d ) where d is the depth of X

3/22

§3 Binary Search Trees

Position Iter_Find( ElementType X, SearchTree T )
{
/* iterative version of Find */
while ( T ) {
if ( X == T->Element )
return T ; /* found */
if ( X < T->Element )
T = T->Left ; /*move down along left path */
else
T = T-> Right ; /* move down along right path */
} /* end while-loop */
return NULL ; /* not found */
}

4/22



FindMin

§3 Binary Search Trees

Position FindMin( SearchTree T )
T( N ) = O ( d )
{
if ( T == NULL )
return NULL; /* not found in an empty tree */
else
if ( T->Left == NULL ) return T; /* found left most */
else return FindMin( T->Left ); /* keep moving to left */
}

 FindMax
Position FindMax( SearchTree T )
T( N ) = O ( d )
{
if ( T != NULL )
while ( T->Right != NULL )
T = T->Right; /* keep moving to find right most */
return T; /* return NULL or the right most */
}

5/22

§3 Binary Search Trees

 Insert
Sketch of the idea:
Insert 80

30
5
2

40
25 35

Insert 35

Insert 25

6/22

 check if 80 is already in the tree
 80 > 40, so it must be the right child
80

of 40

Thisifis35
theis last
nodein the tree
 check
already
we encounter
 35search
< 40, so it must be the left child of 40
when
for the key number.
It will be the parent
 check if 25 is already in the tree
of the new node.
 25 > 5, so it must be the right child of 5

§3 Binary Search Trees
SearchTree Insert( ElementType X, SearchTree T )
{
if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct TreeNode ) );
if ( T == NULL )
FatalError( "Out of space!!!" );
else {
T->Element = X;
How would you
T->Left = T->Right = NULL; }
Handle
T(
N ) = duplicated
O(d)
} /* End creating a one-node tree */
Keys?
else /* If there is a tree */
if ( X < T->Element )
T->Left = Insert( X, T->Left );
else
if ( X > T->Element )
T->Right = Insert( X, T->Right );
/* Else X is in the tree already; we'll do nothing */
return T; /* Do not forget this line!! */
}

7/22

§3 Binary Search Trees

 Delete

 Delete a leaf nodeNote:
: Reset
its kinds
parentoflink
to NULL.
These
nodes
have: degree
atthe
most
1. by its single child.
 Delete a degree 1 node
Replace
node
 Delete a degree 2 node :

 Replace the node by the largest one in its left subtree or
the smallest one in its right subtree.
 Delete the replacing node from the subtree.

〖Example〗 Delete 60

40
20

Solution 1: reset left subtree.

10

60
55
30

50 70

Solution 2: reset right subtree.

45

55
52
52

8/22

§3 Binary Search Trees
SearchTree Delete( ElementType X, SearchTree T )
{ Position TmpCell;
if ( T == NULL ) Error( "Element not found" );
else if ( X < T->Element ) /* Go left */
T->Left = Delete( X, T->Left );
else if ( X > T->Element ) /* Go right */
T->Right = Delete( X, T->Right );
else /* Found element to be deleted */
if ( T->Left && T->Right ) { /* Two children */
/* Replace with smallest in right subtree */
TmpCell = FindMin( T->Right );
T->Element = TmpCell->Element;
T->Right = Delete( T->Element, T->Right ); } /* End if */
else { /* One or zero child */
TmpCell = T;
if ( T->Left == NULL ) /* Also handles 0 child */
T = T->Right;
else if ( T->Right == NULL ) T = T->Left;
free( TmpCell ); } /* End else 1 or 0 child */
return T;
T( N ) = O ( h ) where h is the height of the tree
}
9/22

§3 Binary Search Trees

Note:
If there are not many deletions, then lazy deletion
may be employed: add a flag field to each node, to mark
if a node is active or is deleted. Therefore we can delete
a node without actually freeing the space of that node.
If a deleted key is reinserted, we won’t have to call
malloc again.

While the number of deleted nodes
is the same as the number of active nodes
in the tree, will it seriously affect
the efficiency of the operations?

10/22

§3 Binary Search Trees

4. Average-Case Analysis
Question: Place n elements in a binary search tree. How
high can this tree be?

Answer: The height depends on the order of insertion.
〖Example〗 Given elements 1, 2, 3, 4, 5, 6, 7. Insert
them into a binary search tree in the orders:
4, 2, 1, 3, 6, 5, 7
and
1, 2, 3, 4, 5, 6, 7
4
2
1

6
3

5

h=2

11/22

h=6
7

§3 Binary Search Trees

【Definition】The internal path length for a tree of N nodes
N

is defined to be:

D( N )   d ( i ) , D(1)  0
i 1

where d( i ) is the
depth of work:
node i.
Home

【Theorem】 Assume that all binary search trees are equally
p.139 4.42
likely. Then the average D(N) (taken over all possible
Isomorphic
Trees
insertion sequences)
is O(N log
N). Thus the expected
depth of any node is O(log N).

p.140 4.45
D( N ) = D( i ) + D( N  i  1 ) + N  1
Threaded Trees

Proof:
Since all subtree sizes are
equally likely, the average
i nodes
value of both D( i ) and
N 1
D( N  i  1 ) is [ j  0 D( j )] N .

D( N ) 
12/22

2
N

[ j 0 D( j )]  N  1 =
N 1

root
+1
N  i  1 nodes

p.212-213

= O(N log N)

§4 AVL Trees
Target : Speed up searching (with insertion and
deletion)

root

Tool : Binary search trees
small

large

Problem : Although Tp = O( height ), but the
height can be as bad as O( N ).

13/22

§4 AVL Trees

〖Example〗 3 binary search trees obtained for the months
of the year
Jan

Average search time = ?3.5

Feb

Mar

Apr

June
Aug

May

July

Sept

Dec

Oct

Entered from Jan to Dec

AST = 6.5

Nov

July
Feb

Aug
Apr

May

Jan
Dec

Mar
June

A balanced tree
14/22

What if the months
are entered in
alphabetical order?

Average search time = ?3.1
Oct

Nov

Sept

§4 AVL Trees

Adelson-Velskii-Landis (AVL) Trees (1962)
【Definition】An empty binary tree is height balanced. If T is a
nonempty binary tree with TL and TR as its left and right
subtrees, then T is height balanced iff
(1) TL and TR are height balanced, and
The height of an empty tree
(2) | hL  hR |  1 where hL and hisR defined
are thetoheights
be –1. of TL and TR ,
respectively.

【Definition】The balance factor BF( node ) = hL  hR . In an
AVL tree, BF( node ) = 1, 0, or 1.
4

3
2
1
15/22

5

5

2
6

1
7

8
4 7

3

7

2
1

8
4

3

5

§4 AVL Trees

〖Example〗 Input the months

Mar

May

1
2
0

Mar

Nov
1
2
01
0

1
0

May

Single rotation

May
0

00

00

Mar

Nov

Nov

 The trouble maker Nov is in the right subtree’s right
subtree of the trouble finder Mar. Hence it is called an
RR rotation.
A is not necessarily
In general:
the root of the tree
1

A

RR
0

16/22

1

BR

B
BL

0

RR

BR

B

A

Rotation

AL

AL
BL

A

Insertion

B

0

2

BR
AL

BL

Aug

§4 AVL Trees

Apr
2
1
01
12

1
2
01
1

LL

May
210

00

Mar

Nov

1
010

Rotation

May
00

Aug

Nov

10

0

0

Aug

Apr

Mar

0

Apr
In general:
1
0

2

LL

A

1

Insertion

B

A

17/22

BR

LL

B
AR
BL

B

Rotation

AR
BL

0

BR

0

A
BL
BR

AR

§4 AVL Trees

Jan

21
2
1
01

Double Rotation

1
2
01
0

May

1
010

00

Aug

1
010

Nov

0

10

Apr

Mar

Aug

LR

0

Jan

Mar

1
0

May

0

0

Apr

Jan

0

Nov

Rotation

In general:
1
0

B

A

CL

Insertion

1

B

0

C
BL

2

LR

A

BL

CL

18/22

0 or 1

C

1 or 0

B

AR
CR

OR

0

Rotation

1

C

AR
CR

LR

BL

A
CL

CR
OR

AR

Dec

July

§4 AVL Trees

Feb

1
2
01
21

Mar

1
2
10

Aug

1
0

May

0

01

Apr

Jan

1
0

Nov

Dec

10

01
10

Aug

Jan

1
0

May
0

Nov

0

0

Apr

Feb

July

2

RL

July
0

Mar

1
02
1
0

Rotation
0

0

Dec

1
2
01
1

RL

0

Feb
In general:
1

A
0

RL
0

Insertion

B

1

C

AL
CL

A

CR

CL

19/22

B

0 or 1

C

1 or 0

A
CR

OR

0

Rotation

C

AL
BR

1

BR
AL

B
CL

CR
OR

BR

June

Oct

§4 AVL Trees

Sept
1
0

1
0 2
1
01
21

Jan
Mar
Jan
1
1
12
1
0 1
00
02
1
0
1
1
12
1
0
0 1
Dec
Mar
May
Dec Dec
Mar

1 10

1 Aug
Aug

Aug

0 0

0 Apr
Apr

Apr

0

0

Feb
Feb0
Feb

01
10 1
1
Jan

July
July

1
00

0 July
June

June

2
10

1
0
May
Nov
Nov

1
0 1
0
Nov 0
Oct
May
0
0

June

Note: Several bf’s
might be changed even if
we don’t need to reconstruct
the tree.

Oct 0
Sept

Another option is to keep a height field for each node.

20/22

§4 AVL Trees
AvlTree Insert( ElementType X, AvlTree T )
{ if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct AvlNode ) );
if ( T == NULL ) FatalError( "Out of space!!!" );
else { T->Element = X; T->Height = 0; T->Left = T->Right = NULL; }
} /* End creating a one-node tree */
else if ( X < T->Element ) { /* handle left insertion */
T->Left = Insert( X, T->Left );
if ( Height( T->Left ) - Height( T->Right ) == 2 ) /* not balanced */
if ( X < T->Left->Element ) /* LL Rotation */
T = SingleRotateWithLeft( T );
else /* LR Rotation */
T = DoubleRotateWithLeft( T ); } /* End left */
else if( X > T->Element ) { /* handle right insertion */
T->Right = Insert( X, T->Right );
if ( Height( T->Right ) - Height( T->Left ) == 2 ) /* not balanced */
if ( X > T->Right->Element ) /* RR Rotation */
T = SingleRotateWithRight( T );
else /* RL Rotation */
T = DoubleRotateWithRight( T ); } /* End right */
/* Else X is in the tree already; we'll do nothing */
T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
return T;
}

Home work:

p.136 4.16
Create an AVL Tree
p.136 4.22
Double Rotation

21/22

§4 AVL Trees

Let nh be the minimum number of nodes in a height balanced tree of
height h. Then the tree must look like

A
h2

A
h1

last question:
OROne
h1
h2  nh = nh1 + nh2 + 1

Obviously we have Tp = O( h )
where h is the height of the tree.
But h = ?

Fibonacci numbers:
F0 = 0, F1 = 1, Fi = Fi1 + Fi2 for i > 1
 nh = Fh+2  1, for h  0
i


1  1 5 
Fibonacci number theory gives that Fi 


1  1  5 
 nh 
5  2 
22/22

5

h 2

1

 h  O(lnn)

2




Slide 13

§3 The Search Tree ADT -- Binary Search Trees
1. Definition
【Definition】A binary search tree is a binary tree. It may be
(1)
(2)
(3)
(4)

empty. If it is not empty, it satisfies the following properties:
Every node has a key which is an integer, and the keys are
distinct.
The keys in a nonempty left subtree must be smaller than
the key in the root of the subtree.
The keys in a nonempty right subtree must be larger than
the key in the root of the subtree.
The left and right subtrees are also binary search trees.

30

5
2

1/22

60

40

20
70

65

15
80

12

10

25
22

§3 Binary Search Trees

2. ADT
Objects: A finite ordered list with zero or more elements.
Operations:

 SearchTree MakeEmpty( SearchTree T );
 Position Find( ElementType X, SearchTree T );
 Position FindMin( SearchTree T );
 Position FindMax( SearchTree T );
 SearchTree Insert( ElementType X, SearchTree T );
 SearchTree Delete( ElementType X, SearchTree T );
 ElementType Retrieve( Position P );

2/22

§3 Binary Search Trees

3. Implementations

 Find

Must this test
be performed first?

Position Find( ElementType X, SearchTree T )
{
if ( T == NULL )
These are
return NULL; /* not found in an empty tree */
tail recursions.
if ( X < T->Element ) /* if smaller than root */
return Find( X, T->Left ); /* search left subtree */
else
if ( X > T->Element ) /* if larger than root */
return Find( X, T->Right ); /* search right subtree */
else /* if X == root */
return T; /* found */
}
T( N ) = S ( N ) = O( d ) where d is the depth of X

3/22

§3 Binary Search Trees

Position Iter_Find( ElementType X, SearchTree T )
{
/* iterative version of Find */
while ( T ) {
if ( X == T->Element )
return T ; /* found */
if ( X < T->Element )
T = T->Left ; /*move down along left path */
else
T = T-> Right ; /* move down along right path */
} /* end while-loop */
return NULL ; /* not found */
}

4/22



FindMin

§3 Binary Search Trees

Position FindMin( SearchTree T )
T( N ) = O ( d )
{
if ( T == NULL )
return NULL; /* not found in an empty tree */
else
if ( T->Left == NULL ) return T; /* found left most */
else return FindMin( T->Left ); /* keep moving to left */
}

 FindMax
Position FindMax( SearchTree T )
T( N ) = O ( d )
{
if ( T != NULL )
while ( T->Right != NULL )
T = T->Right; /* keep moving to find right most */
return T; /* return NULL or the right most */
}

5/22

§3 Binary Search Trees

 Insert
Sketch of the idea:
Insert 80

30
5
2

40
25 35

Insert 35

Insert 25

6/22

 check if 80 is already in the tree
 80 > 40, so it must be the right child
80

of 40

Thisifis35
theis last
nodein the tree
 check
already
we encounter
 35search
< 40, so it must be the left child of 40
when
for the key number.
It will be the parent
 check if 25 is already in the tree
of the new node.
 25 > 5, so it must be the right child of 5

§3 Binary Search Trees
SearchTree Insert( ElementType X, SearchTree T )
{
if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct TreeNode ) );
if ( T == NULL )
FatalError( "Out of space!!!" );
else {
T->Element = X;
How would you
T->Left = T->Right = NULL; }
Handle
T(
N ) = duplicated
O(d)
} /* End creating a one-node tree */
Keys?
else /* If there is a tree */
if ( X < T->Element )
T->Left = Insert( X, T->Left );
else
if ( X > T->Element )
T->Right = Insert( X, T->Right );
/* Else X is in the tree already; we'll do nothing */
return T; /* Do not forget this line!! */
}

7/22

§3 Binary Search Trees

 Delete

 Delete a leaf nodeNote:
: Reset
its kinds
parentoflink
to NULL.
These
nodes
have: degree
atthe
most
1. by its single child.
 Delete a degree 1 node
Replace
node
 Delete a degree 2 node :

 Replace the node by the largest one in its left subtree or
the smallest one in its right subtree.
 Delete the replacing node from the subtree.

〖Example〗 Delete 60

40
20

Solution 1: reset left subtree.

10

60
55
30

50 70

Solution 2: reset right subtree.

45

55
52
52

8/22

§3 Binary Search Trees
SearchTree Delete( ElementType X, SearchTree T )
{ Position TmpCell;
if ( T == NULL ) Error( "Element not found" );
else if ( X < T->Element ) /* Go left */
T->Left = Delete( X, T->Left );
else if ( X > T->Element ) /* Go right */
T->Right = Delete( X, T->Right );
else /* Found element to be deleted */
if ( T->Left && T->Right ) { /* Two children */
/* Replace with smallest in right subtree */
TmpCell = FindMin( T->Right );
T->Element = TmpCell->Element;
T->Right = Delete( T->Element, T->Right ); } /* End if */
else { /* One or zero child */
TmpCell = T;
if ( T->Left == NULL ) /* Also handles 0 child */
T = T->Right;
else if ( T->Right == NULL ) T = T->Left;
free( TmpCell ); } /* End else 1 or 0 child */
return T;
T( N ) = O ( h ) where h is the height of the tree
}
9/22

§3 Binary Search Trees

Note:
If there are not many deletions, then lazy deletion
may be employed: add a flag field to each node, to mark
if a node is active or is deleted. Therefore we can delete
a node without actually freeing the space of that node.
If a deleted key is reinserted, we won’t have to call
malloc again.

While the number of deleted nodes
is the same as the number of active nodes
in the tree, will it seriously affect
the efficiency of the operations?

10/22

§3 Binary Search Trees

4. Average-Case Analysis
Question: Place n elements in a binary search tree. How
high can this tree be?

Answer: The height depends on the order of insertion.
〖Example〗 Given elements 1, 2, 3, 4, 5, 6, 7. Insert
them into a binary search tree in the orders:
4, 2, 1, 3, 6, 5, 7
and
1, 2, 3, 4, 5, 6, 7
4
2
1

6
3

5

h=2

11/22

h=6
7

§3 Binary Search Trees

【Definition】The internal path length for a tree of N nodes
N

is defined to be:

D( N )   d ( i ) , D(1)  0
i 1

where d( i ) is the
depth of work:
node i.
Home

【Theorem】 Assume that all binary search trees are equally
p.139 4.42
likely. Then the average D(N) (taken over all possible
Isomorphic
Trees
insertion sequences)
is O(N log
N). Thus the expected
depth of any node is O(log N).

p.140 4.45
D( N ) = D( i ) + D( N  i  1 ) + N  1
Threaded Trees

Proof:
Since all subtree sizes are
equally likely, the average
i nodes
value of both D( i ) and
N 1
D( N  i  1 ) is [ j  0 D( j )] N .

D( N ) 
12/22

2
N

[ j 0 D( j )]  N  1 =
N 1

root
+1
N  i  1 nodes

p.212-213

= O(N log N)

§4 AVL Trees
Target : Speed up searching (with insertion and
deletion)

root

Tool : Binary search trees
small

large

Problem : Although Tp = O( height ), but the
height can be as bad as O( N ).

13/22

§4 AVL Trees

〖Example〗 3 binary search trees obtained for the months
of the year
Jan

Average search time = ?3.5

Feb

Mar

Apr

June
Aug

May

July

Sept

Dec

Oct

Entered from Jan to Dec

AST = 6.5

Nov

July
Feb

Aug
Apr

May

Jan
Dec

Mar
June

A balanced tree
14/22

What if the months
are entered in
alphabetical order?

Average search time = ?3.1
Oct

Nov

Sept

§4 AVL Trees

Adelson-Velskii-Landis (AVL) Trees (1962)
【Definition】An empty binary tree is height balanced. If T is a
nonempty binary tree with TL and TR as its left and right
subtrees, then T is height balanced iff
(1) TL and TR are height balanced, and
The height of an empty tree
(2) | hL  hR |  1 where hL and hisR defined
are thetoheights
be –1. of TL and TR ,
respectively.

【Definition】The balance factor BF( node ) = hL  hR . In an
AVL tree, BF( node ) = 1, 0, or 1.
4

3
2
1
15/22

5

5

2
6

1
7

8
4 7

3

7

2
1

8
4

3

5

§4 AVL Trees

〖Example〗 Input the months

Mar

May

1
2
0

Mar

Nov
1
2
01
0

1
0

May

Single rotation

May
0

00

00

Mar

Nov

Nov

 The trouble maker Nov is in the right subtree’s right
subtree of the trouble finder Mar. Hence it is called an
RR rotation.
A is not necessarily
In general:
the root of the tree
1

A

RR
0

16/22

1

BR

B
BL

0

RR

BR

B

A

Rotation

AL

AL
BL

A

Insertion

B

0

2

BR
AL

BL

Aug

§4 AVL Trees

Apr
2
1
01
12

1
2
01
1

LL

May
210

00

Mar

Nov

1
010

Rotation

May
00

Aug

Nov

10

0

0

Aug

Apr

Mar

0

Apr
In general:
1
0

2

LL

A

1

Insertion

B

A

17/22

BR

LL

B
AR
BL

B

Rotation

AR
BL

0

BR

0

A
BL
BR

AR

§4 AVL Trees

Jan

21
2
1
01

Double Rotation

1
2
01
0

May

1
010

00

Aug

1
010

Nov

0

10

Apr

Mar

Aug

LR

0

Jan

Mar

1
0

May

0

0

Apr

Jan

0

Nov

Rotation

In general:
1
0

B

A

CL

Insertion

1

B

0

C
BL

2

LR

A

BL

CL

18/22

0 or 1

C

1 or 0

B

AR
CR

OR

0

Rotation

1

C

AR
CR

LR

BL

A
CL

CR
OR

AR

Dec

July

§4 AVL Trees

Feb

1
2
01
21

Mar

1
2
10

Aug

1
0

May

0

01

Apr

Jan

1
0

Nov

Dec

10

01
10

Aug

Jan

1
0

May
0

Nov

0

0

Apr

Feb

July

2

RL

July
0

Mar

1
02
1
0

Rotation
0

0

Dec

1
2
01
1

RL

0

Feb
In general:
1

A
0

RL
0

Insertion

B

1

C

AL
CL

A

CR

CL

19/22

B

0 or 1

C

1 or 0

A
CR

OR

0

Rotation

C

AL
BR

1

BR
AL

B
CL

CR
OR

BR

June

Oct

§4 AVL Trees

Sept
1
0

1
0 2
1
01
21

Jan
Mar
Jan
1
1
12
1
0 1
00
02
1
0
1
1
12
1
0
0 1
Dec
Mar
May
Dec Dec
Mar

1 10

1 Aug
Aug

Aug

0 0

0 Apr
Apr

Apr

0

0

Feb
Feb0
Feb

01
10 1
1
Jan

July
July

1
00

0 July
June

June

2
10

1
0
May
Nov
Nov

1
0 1
0
Nov 0
Oct
May
0
0

June

Note: Several bf’s
might be changed even if
we don’t need to reconstruct
the tree.

Oct 0
Sept

Another option is to keep a height field for each node.

20/22

§4 AVL Trees
AvlTree Insert( ElementType X, AvlTree T )
{ if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct AvlNode ) );
if ( T == NULL ) FatalError( "Out of space!!!" );
else { T->Element = X; T->Height = 0; T->Left = T->Right = NULL; }
} /* End creating a one-node tree */
else if ( X < T->Element ) { /* handle left insertion */
T->Left = Insert( X, T->Left );
if ( Height( T->Left ) - Height( T->Right ) == 2 ) /* not balanced */
if ( X < T->Left->Element ) /* LL Rotation */
T = SingleRotateWithLeft( T );
else /* LR Rotation */
T = DoubleRotateWithLeft( T ); } /* End left */
else if( X > T->Element ) { /* handle right insertion */
T->Right = Insert( X, T->Right );
if ( Height( T->Right ) - Height( T->Left ) == 2 ) /* not balanced */
if ( X > T->Right->Element ) /* RR Rotation */
T = SingleRotateWithRight( T );
else /* RL Rotation */
T = DoubleRotateWithRight( T ); } /* End right */
/* Else X is in the tree already; we'll do nothing */
T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
return T;
}

Home work:

p.136 4.16
Create an AVL Tree
p.136 4.22
Double Rotation

21/22

§4 AVL Trees

Let nh be the minimum number of nodes in a height balanced tree of
height h. Then the tree must look like

A
h2

A
h1

last question:
OROne
h1
h2  nh = nh1 + nh2 + 1

Obviously we have Tp = O( h )
where h is the height of the tree.
But h = ?

Fibonacci numbers:
F0 = 0, F1 = 1, Fi = Fi1 + Fi2 for i > 1
 nh = Fh+2  1, for h  0
i


1  1 5 
Fibonacci number theory gives that Fi 


1  1  5 
 nh 
5  2 
22/22

5

h 2

1

 h  O(lnn)

2




Slide 14

§3 The Search Tree ADT -- Binary Search Trees
1. Definition
【Definition】A binary search tree is a binary tree. It may be
(1)
(2)
(3)
(4)

empty. If it is not empty, it satisfies the following properties:
Every node has a key which is an integer, and the keys are
distinct.
The keys in a nonempty left subtree must be smaller than
the key in the root of the subtree.
The keys in a nonempty right subtree must be larger than
the key in the root of the subtree.
The left and right subtrees are also binary search trees.

30

5
2

1/22

60

40

20
70

65

15
80

12

10

25
22

§3 Binary Search Trees

2. ADT
Objects: A finite ordered list with zero or more elements.
Operations:

 SearchTree MakeEmpty( SearchTree T );
 Position Find( ElementType X, SearchTree T );
 Position FindMin( SearchTree T );
 Position FindMax( SearchTree T );
 SearchTree Insert( ElementType X, SearchTree T );
 SearchTree Delete( ElementType X, SearchTree T );
 ElementType Retrieve( Position P );

2/22

§3 Binary Search Trees

3. Implementations

 Find

Must this test
be performed first?

Position Find( ElementType X, SearchTree T )
{
if ( T == NULL )
These are
return NULL; /* not found in an empty tree */
tail recursions.
if ( X < T->Element ) /* if smaller than root */
return Find( X, T->Left ); /* search left subtree */
else
if ( X > T->Element ) /* if larger than root */
return Find( X, T->Right ); /* search right subtree */
else /* if X == root */
return T; /* found */
}
T( N ) = S ( N ) = O( d ) where d is the depth of X

3/22

§3 Binary Search Trees

Position Iter_Find( ElementType X, SearchTree T )
{
/* iterative version of Find */
while ( T ) {
if ( X == T->Element )
return T ; /* found */
if ( X < T->Element )
T = T->Left ; /*move down along left path */
else
T = T-> Right ; /* move down along right path */
} /* end while-loop */
return NULL ; /* not found */
}

4/22



FindMin

§3 Binary Search Trees

Position FindMin( SearchTree T )
T( N ) = O ( d )
{
if ( T == NULL )
return NULL; /* not found in an empty tree */
else
if ( T->Left == NULL ) return T; /* found left most */
else return FindMin( T->Left ); /* keep moving to left */
}

 FindMax
Position FindMax( SearchTree T )
T( N ) = O ( d )
{
if ( T != NULL )
while ( T->Right != NULL )
T = T->Right; /* keep moving to find right most */
return T; /* return NULL or the right most */
}

5/22

§3 Binary Search Trees

 Insert
Sketch of the idea:
Insert 80

30
5
2

40
25 35

Insert 35

Insert 25

6/22

 check if 80 is already in the tree
 80 > 40, so it must be the right child
80

of 40

Thisifis35
theis last
nodein the tree
 check
already
we encounter
 35search
< 40, so it must be the left child of 40
when
for the key number.
It will be the parent
 check if 25 is already in the tree
of the new node.
 25 > 5, so it must be the right child of 5

§3 Binary Search Trees
SearchTree Insert( ElementType X, SearchTree T )
{
if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct TreeNode ) );
if ( T == NULL )
FatalError( "Out of space!!!" );
else {
T->Element = X;
How would you
T->Left = T->Right = NULL; }
Handle
T(
N ) = duplicated
O(d)
} /* End creating a one-node tree */
Keys?
else /* If there is a tree */
if ( X < T->Element )
T->Left = Insert( X, T->Left );
else
if ( X > T->Element )
T->Right = Insert( X, T->Right );
/* Else X is in the tree already; we'll do nothing */
return T; /* Do not forget this line!! */
}

7/22

§3 Binary Search Trees

 Delete

 Delete a leaf nodeNote:
: Reset
its kinds
parentoflink
to NULL.
These
nodes
have: degree
atthe
most
1. by its single child.
 Delete a degree 1 node
Replace
node
 Delete a degree 2 node :

 Replace the node by the largest one in its left subtree or
the smallest one in its right subtree.
 Delete the replacing node from the subtree.

〖Example〗 Delete 60

40
20

Solution 1: reset left subtree.

10

60
55
30

50 70

Solution 2: reset right subtree.

45

55
52
52

8/22

§3 Binary Search Trees
SearchTree Delete( ElementType X, SearchTree T )
{ Position TmpCell;
if ( T == NULL ) Error( "Element not found" );
else if ( X < T->Element ) /* Go left */
T->Left = Delete( X, T->Left );
else if ( X > T->Element ) /* Go right */
T->Right = Delete( X, T->Right );
else /* Found element to be deleted */
if ( T->Left && T->Right ) { /* Two children */
/* Replace with smallest in right subtree */
TmpCell = FindMin( T->Right );
T->Element = TmpCell->Element;
T->Right = Delete( T->Element, T->Right ); } /* End if */
else { /* One or zero child */
TmpCell = T;
if ( T->Left == NULL ) /* Also handles 0 child */
T = T->Right;
else if ( T->Right == NULL ) T = T->Left;
free( TmpCell ); } /* End else 1 or 0 child */
return T;
T( N ) = O ( h ) where h is the height of the tree
}
9/22

§3 Binary Search Trees

Note:
If there are not many deletions, then lazy deletion
may be employed: add a flag field to each node, to mark
if a node is active or is deleted. Therefore we can delete
a node without actually freeing the space of that node.
If a deleted key is reinserted, we won’t have to call
malloc again.

While the number of deleted nodes
is the same as the number of active nodes
in the tree, will it seriously affect
the efficiency of the operations?

10/22

§3 Binary Search Trees

4. Average-Case Analysis
Question: Place n elements in a binary search tree. How
high can this tree be?

Answer: The height depends on the order of insertion.
〖Example〗 Given elements 1, 2, 3, 4, 5, 6, 7. Insert
them into a binary search tree in the orders:
4, 2, 1, 3, 6, 5, 7
and
1, 2, 3, 4, 5, 6, 7
4
2
1

6
3

5

h=2

11/22

h=6
7

§3 Binary Search Trees

【Definition】The internal path length for a tree of N nodes
N

is defined to be:

D( N )   d ( i ) , D(1)  0
i 1

where d( i ) is the
depth of work:
node i.
Home

【Theorem】 Assume that all binary search trees are equally
p.139 4.42
likely. Then the average D(N) (taken over all possible
Isomorphic
Trees
insertion sequences)
is O(N log
N). Thus the expected
depth of any node is O(log N).

p.140 4.45
D( N ) = D( i ) + D( N  i  1 ) + N  1
Threaded Trees

Proof:
Since all subtree sizes are
equally likely, the average
i nodes
value of both D( i ) and
N 1
D( N  i  1 ) is [ j  0 D( j )] N .

D( N ) 
12/22

2
N

[ j 0 D( j )]  N  1 =
N 1

root
+1
N  i  1 nodes

p.212-213

= O(N log N)

§4 AVL Trees
Target : Speed up searching (with insertion and
deletion)

root

Tool : Binary search trees
small

large

Problem : Although Tp = O( height ), but the
height can be as bad as O( N ).

13/22

§4 AVL Trees

〖Example〗 3 binary search trees obtained for the months
of the year
Jan

Average search time = ?3.5

Feb

Mar

Apr

June
Aug

May

July

Sept

Dec

Oct

Entered from Jan to Dec

AST = 6.5

Nov

July
Feb

Aug
Apr

May

Jan
Dec

Mar
June

A balanced tree
14/22

What if the months
are entered in
alphabetical order?

Average search time = ?3.1
Oct

Nov

Sept

§4 AVL Trees

Adelson-Velskii-Landis (AVL) Trees (1962)
【Definition】An empty binary tree is height balanced. If T is a
nonempty binary tree with TL and TR as its left and right
subtrees, then T is height balanced iff
(1) TL and TR are height balanced, and
The height of an empty tree
(2) | hL  hR |  1 where hL and hisR defined
are thetoheights
be –1. of TL and TR ,
respectively.

【Definition】The balance factor BF( node ) = hL  hR . In an
AVL tree, BF( node ) = 1, 0, or 1.
4

3
2
1
15/22

5

5

2
6

1
7

8
4 7

3

7

2
1

8
4

3

5

§4 AVL Trees

〖Example〗 Input the months

Mar

May

1
2
0

Mar

Nov
1
2
01
0

1
0

May

Single rotation

May
0

00

00

Mar

Nov

Nov

 The trouble maker Nov is in the right subtree’s right
subtree of the trouble finder Mar. Hence it is called an
RR rotation.
A is not necessarily
In general:
the root of the tree
1

A

RR
0

16/22

1

BR

B
BL

0

RR

BR

B

A

Rotation

AL

AL
BL

A

Insertion

B

0

2

BR
AL

BL

Aug

§4 AVL Trees

Apr
2
1
01
12

1
2
01
1

LL

May
210

00

Mar

Nov

1
010

Rotation

May
00

Aug

Nov

10

0

0

Aug

Apr

Mar

0

Apr
In general:
1
0

2

LL

A

1

Insertion

B

A

17/22

BR

LL

B
AR
BL

B

Rotation

AR
BL

0

BR

0

A
BL
BR

AR

§4 AVL Trees

Jan

21
2
1
01

Double Rotation

1
2
01
0

May

1
010

00

Aug

1
010

Nov

0

10

Apr

Mar

Aug

LR

0

Jan

Mar

1
0

May

0

0

Apr

Jan

0

Nov

Rotation

In general:
1
0

B

A

CL

Insertion

1

B

0

C
BL

2

LR

A

BL

CL

18/22

0 or 1

C

1 or 0

B

AR
CR

OR

0

Rotation

1

C

AR
CR

LR

BL

A
CL

CR
OR

AR

Dec

July

§4 AVL Trees

Feb

1
2
01
21

Mar

1
2
10

Aug

1
0

May

0

01

Apr

Jan

1
0

Nov

Dec

10

01
10

Aug

Jan

1
0

May
0

Nov

0

0

Apr

Feb

July

2

RL

July
0

Mar

1
02
1
0

Rotation
0

0

Dec

1
2
01
1

RL

0

Feb
In general:
1

A
0

RL
0

Insertion

B

1

C

AL
CL

A

CR

CL

19/22

B

0 or 1

C

1 or 0

A
CR

OR

0

Rotation

C

AL
BR

1

BR
AL

B
CL

CR
OR

BR

June

Oct

§4 AVL Trees

Sept
1
0

1
0 2
1
01
21

Jan
Mar
Jan
1
1
12
1
0 1
00
02
1
0
1
1
12
1
0
0 1
Dec
Mar
May
Dec Dec
Mar

1 10

1 Aug
Aug

Aug

0 0

0 Apr
Apr

Apr

0

0

Feb
Feb0
Feb

01
10 1
1
Jan

July
July

1
00

0 July
June

June

2
10

1
0
May
Nov
Nov

1
0 1
0
Nov 0
Oct
May
0
0

June

Note: Several bf’s
might be changed even if
we don’t need to reconstruct
the tree.

Oct 0
Sept

Another option is to keep a height field for each node.

20/22

§4 AVL Trees
AvlTree Insert( ElementType X, AvlTree T )
{ if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct AvlNode ) );
if ( T == NULL ) FatalError( "Out of space!!!" );
else { T->Element = X; T->Height = 0; T->Left = T->Right = NULL; }
} /* End creating a one-node tree */
else if ( X < T->Element ) { /* handle left insertion */
T->Left = Insert( X, T->Left );
if ( Height( T->Left ) - Height( T->Right ) == 2 ) /* not balanced */
if ( X < T->Left->Element ) /* LL Rotation */
T = SingleRotateWithLeft( T );
else /* LR Rotation */
T = DoubleRotateWithLeft( T ); } /* End left */
else if( X > T->Element ) { /* handle right insertion */
T->Right = Insert( X, T->Right );
if ( Height( T->Right ) - Height( T->Left ) == 2 ) /* not balanced */
if ( X > T->Right->Element ) /* RR Rotation */
T = SingleRotateWithRight( T );
else /* RL Rotation */
T = DoubleRotateWithRight( T ); } /* End right */
/* Else X is in the tree already; we'll do nothing */
T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
return T;
}

Home work:

p.136 4.16
Create an AVL Tree
p.136 4.22
Double Rotation

21/22

§4 AVL Trees

Let nh be the minimum number of nodes in a height balanced tree of
height h. Then the tree must look like

A
h2

A
h1

last question:
OROne
h1
h2  nh = nh1 + nh2 + 1

Obviously we have Tp = O( h )
where h is the height of the tree.
But h = ?

Fibonacci numbers:
F0 = 0, F1 = 1, Fi = Fi1 + Fi2 for i > 1
 nh = Fh+2  1, for h  0
i


1  1 5 
Fibonacci number theory gives that Fi 


1  1  5 
 nh 
5  2 
22/22

5

h 2

1

 h  O(lnn)

2




Slide 15

§3 The Search Tree ADT -- Binary Search Trees
1. Definition
【Definition】A binary search tree is a binary tree. It may be
(1)
(2)
(3)
(4)

empty. If it is not empty, it satisfies the following properties:
Every node has a key which is an integer, and the keys are
distinct.
The keys in a nonempty left subtree must be smaller than
the key in the root of the subtree.
The keys in a nonempty right subtree must be larger than
the key in the root of the subtree.
The left and right subtrees are also binary search trees.

30

5
2

1/22

60

40

20
70

65

15
80

12

10

25
22

§3 Binary Search Trees

2. ADT
Objects: A finite ordered list with zero or more elements.
Operations:

 SearchTree MakeEmpty( SearchTree T );
 Position Find( ElementType X, SearchTree T );
 Position FindMin( SearchTree T );
 Position FindMax( SearchTree T );
 SearchTree Insert( ElementType X, SearchTree T );
 SearchTree Delete( ElementType X, SearchTree T );
 ElementType Retrieve( Position P );

2/22

§3 Binary Search Trees

3. Implementations

 Find

Must this test
be performed first?

Position Find( ElementType X, SearchTree T )
{
if ( T == NULL )
These are
return NULL; /* not found in an empty tree */
tail recursions.
if ( X < T->Element ) /* if smaller than root */
return Find( X, T->Left ); /* search left subtree */
else
if ( X > T->Element ) /* if larger than root */
return Find( X, T->Right ); /* search right subtree */
else /* if X == root */
return T; /* found */
}
T( N ) = S ( N ) = O( d ) where d is the depth of X

3/22

§3 Binary Search Trees

Position Iter_Find( ElementType X, SearchTree T )
{
/* iterative version of Find */
while ( T ) {
if ( X == T->Element )
return T ; /* found */
if ( X < T->Element )
T = T->Left ; /*move down along left path */
else
T = T-> Right ; /* move down along right path */
} /* end while-loop */
return NULL ; /* not found */
}

4/22



FindMin

§3 Binary Search Trees

Position FindMin( SearchTree T )
T( N ) = O ( d )
{
if ( T == NULL )
return NULL; /* not found in an empty tree */
else
if ( T->Left == NULL ) return T; /* found left most */
else return FindMin( T->Left ); /* keep moving to left */
}

 FindMax
Position FindMax( SearchTree T )
T( N ) = O ( d )
{
if ( T != NULL )
while ( T->Right != NULL )
T = T->Right; /* keep moving to find right most */
return T; /* return NULL or the right most */
}

5/22

§3 Binary Search Trees

 Insert
Sketch of the idea:
Insert 80

30
5
2

40
25 35

Insert 35

Insert 25

6/22

 check if 80 is already in the tree
 80 > 40, so it must be the right child
80

of 40

Thisifis35
theis last
nodein the tree
 check
already
we encounter
 35search
< 40, so it must be the left child of 40
when
for the key number.
It will be the parent
 check if 25 is already in the tree
of the new node.
 25 > 5, so it must be the right child of 5

§3 Binary Search Trees
SearchTree Insert( ElementType X, SearchTree T )
{
if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct TreeNode ) );
if ( T == NULL )
FatalError( "Out of space!!!" );
else {
T->Element = X;
How would you
T->Left = T->Right = NULL; }
Handle
T(
N ) = duplicated
O(d)
} /* End creating a one-node tree */
Keys?
else /* If there is a tree */
if ( X < T->Element )
T->Left = Insert( X, T->Left );
else
if ( X > T->Element )
T->Right = Insert( X, T->Right );
/* Else X is in the tree already; we'll do nothing */
return T; /* Do not forget this line!! */
}

7/22

§3 Binary Search Trees

 Delete

 Delete a leaf nodeNote:
: Reset
its kinds
parentoflink
to NULL.
These
nodes
have: degree
atthe
most
1. by its single child.
 Delete a degree 1 node
Replace
node
 Delete a degree 2 node :

 Replace the node by the largest one in its left subtree or
the smallest one in its right subtree.
 Delete the replacing node from the subtree.

〖Example〗 Delete 60

40
20

Solution 1: reset left subtree.

10

60
55
30

50 70

Solution 2: reset right subtree.

45

55
52
52

8/22

§3 Binary Search Trees
SearchTree Delete( ElementType X, SearchTree T )
{ Position TmpCell;
if ( T == NULL ) Error( "Element not found" );
else if ( X < T->Element ) /* Go left */
T->Left = Delete( X, T->Left );
else if ( X > T->Element ) /* Go right */
T->Right = Delete( X, T->Right );
else /* Found element to be deleted */
if ( T->Left && T->Right ) { /* Two children */
/* Replace with smallest in right subtree */
TmpCell = FindMin( T->Right );
T->Element = TmpCell->Element;
T->Right = Delete( T->Element, T->Right ); } /* End if */
else { /* One or zero child */
TmpCell = T;
if ( T->Left == NULL ) /* Also handles 0 child */
T = T->Right;
else if ( T->Right == NULL ) T = T->Left;
free( TmpCell ); } /* End else 1 or 0 child */
return T;
T( N ) = O ( h ) where h is the height of the tree
}
9/22

§3 Binary Search Trees

Note:
If there are not many deletions, then lazy deletion
may be employed: add a flag field to each node, to mark
if a node is active or is deleted. Therefore we can delete
a node without actually freeing the space of that node.
If a deleted key is reinserted, we won’t have to call
malloc again.

While the number of deleted nodes
is the same as the number of active nodes
in the tree, will it seriously affect
the efficiency of the operations?

10/22

§3 Binary Search Trees

4. Average-Case Analysis
Question: Place n elements in a binary search tree. How
high can this tree be?

Answer: The height depends on the order of insertion.
〖Example〗 Given elements 1, 2, 3, 4, 5, 6, 7. Insert
them into a binary search tree in the orders:
4, 2, 1, 3, 6, 5, 7
and
1, 2, 3, 4, 5, 6, 7
4
2
1

6
3

5

h=2

11/22

h=6
7

§3 Binary Search Trees

【Definition】The internal path length for a tree of N nodes
N

is defined to be:

D( N )   d ( i ) , D(1)  0
i 1

where d( i ) is the
depth of work:
node i.
Home

【Theorem】 Assume that all binary search trees are equally
p.139 4.42
likely. Then the average D(N) (taken over all possible
Isomorphic
Trees
insertion sequences)
is O(N log
N). Thus the expected
depth of any node is O(log N).

p.140 4.45
D( N ) = D( i ) + D( N  i  1 ) + N  1
Threaded Trees

Proof:
Since all subtree sizes are
equally likely, the average
i nodes
value of both D( i ) and
N 1
D( N  i  1 ) is [ j  0 D( j )] N .

D( N ) 
12/22

2
N

[ j 0 D( j )]  N  1 =
N 1

root
+1
N  i  1 nodes

p.212-213

= O(N log N)

§4 AVL Trees
Target : Speed up searching (with insertion and
deletion)

root

Tool : Binary search trees
small

large

Problem : Although Tp = O( height ), but the
height can be as bad as O( N ).

13/22

§4 AVL Trees

〖Example〗 3 binary search trees obtained for the months
of the year
Jan

Average search time = ?3.5

Feb

Mar

Apr

June
Aug

May

July

Sept

Dec

Oct

Entered from Jan to Dec

AST = 6.5

Nov

July
Feb

Aug
Apr

May

Jan
Dec

Mar
June

A balanced tree
14/22

What if the months
are entered in
alphabetical order?

Average search time = ?3.1
Oct

Nov

Sept

§4 AVL Trees

Adelson-Velskii-Landis (AVL) Trees (1962)
【Definition】An empty binary tree is height balanced. If T is a
nonempty binary tree with TL and TR as its left and right
subtrees, then T is height balanced iff
(1) TL and TR are height balanced, and
The height of an empty tree
(2) | hL  hR |  1 where hL and hisR defined
are thetoheights
be –1. of TL and TR ,
respectively.

【Definition】The balance factor BF( node ) = hL  hR . In an
AVL tree, BF( node ) = 1, 0, or 1.
4

3
2
1
15/22

5

5

2
6

1
7

8
4 7

3

7

2
1

8
4

3

5

§4 AVL Trees

〖Example〗 Input the months

Mar

May

1
2
0

Mar

Nov
1
2
01
0

1
0

May

Single rotation

May
0

00

00

Mar

Nov

Nov

 The trouble maker Nov is in the right subtree’s right
subtree of the trouble finder Mar. Hence it is called an
RR rotation.
A is not necessarily
In general:
the root of the tree
1

A

RR
0

16/22

1

BR

B
BL

0

RR

BR

B

A

Rotation

AL

AL
BL

A

Insertion

B

0

2

BR
AL

BL

Aug

§4 AVL Trees

Apr
2
1
01
12

1
2
01
1

LL

May
210

00

Mar

Nov

1
010

Rotation

May
00

Aug

Nov

10

0

0

Aug

Apr

Mar

0

Apr
In general:
1
0

2

LL

A

1

Insertion

B

A

17/22

BR

LL

B
AR
BL

B

Rotation

AR
BL

0

BR

0

A
BL
BR

AR

§4 AVL Trees

Jan

21
2
1
01

Double Rotation

1
2
01
0

May

1
010

00

Aug

1
010

Nov

0

10

Apr

Mar

Aug

LR

0

Jan

Mar

1
0

May

0

0

Apr

Jan

0

Nov

Rotation

In general:
1
0

B

A

CL

Insertion

1

B

0

C
BL

2

LR

A

BL

CL

18/22

0 or 1

C

1 or 0

B

AR
CR

OR

0

Rotation

1

C

AR
CR

LR

BL

A
CL

CR
OR

AR

Dec

July

§4 AVL Trees

Feb

1
2
01
21

Mar

1
2
10

Aug

1
0

May

0

01

Apr

Jan

1
0

Nov

Dec

10

01
10

Aug

Jan

1
0

May
0

Nov

0

0

Apr

Feb

July

2

RL

July
0

Mar

1
02
1
0

Rotation
0

0

Dec

1
2
01
1

RL

0

Feb
In general:
1

A
0

RL
0

Insertion

B

1

C

AL
CL

A

CR

CL

19/22

B

0 or 1

C

1 or 0

A
CR

OR

0

Rotation

C

AL
BR

1

BR
AL

B
CL

CR
OR

BR

June

Oct

§4 AVL Trees

Sept
1
0

1
0 2
1
01
21

Jan
Mar
Jan
1
1
12
1
0 1
00
02
1
0
1
1
12
1
0
0 1
Dec
Mar
May
Dec Dec
Mar

1 10

1 Aug
Aug

Aug

0 0

0 Apr
Apr

Apr

0

0

Feb
Feb0
Feb

01
10 1
1
Jan

July
July

1
00

0 July
June

June

2
10

1
0
May
Nov
Nov

1
0 1
0
Nov 0
Oct
May
0
0

June

Note: Several bf’s
might be changed even if
we don’t need to reconstruct
the tree.

Oct 0
Sept

Another option is to keep a height field for each node.

20/22

§4 AVL Trees
AvlTree Insert( ElementType X, AvlTree T )
{ if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct AvlNode ) );
if ( T == NULL ) FatalError( "Out of space!!!" );
else { T->Element = X; T->Height = 0; T->Left = T->Right = NULL; }
} /* End creating a one-node tree */
else if ( X < T->Element ) { /* handle left insertion */
T->Left = Insert( X, T->Left );
if ( Height( T->Left ) - Height( T->Right ) == 2 ) /* not balanced */
if ( X < T->Left->Element ) /* LL Rotation */
T = SingleRotateWithLeft( T );
else /* LR Rotation */
T = DoubleRotateWithLeft( T ); } /* End left */
else if( X > T->Element ) { /* handle right insertion */
T->Right = Insert( X, T->Right );
if ( Height( T->Right ) - Height( T->Left ) == 2 ) /* not balanced */
if ( X > T->Right->Element ) /* RR Rotation */
T = SingleRotateWithRight( T );
else /* RL Rotation */
T = DoubleRotateWithRight( T ); } /* End right */
/* Else X is in the tree already; we'll do nothing */
T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
return T;
}

Home work:

p.136 4.16
Create an AVL Tree
p.136 4.22
Double Rotation

21/22

§4 AVL Trees

Let nh be the minimum number of nodes in a height balanced tree of
height h. Then the tree must look like

A
h2

A
h1

last question:
OROne
h1
h2  nh = nh1 + nh2 + 1

Obviously we have Tp = O( h )
where h is the height of the tree.
But h = ?

Fibonacci numbers:
F0 = 0, F1 = 1, Fi = Fi1 + Fi2 for i > 1
 nh = Fh+2  1, for h  0
i


1  1 5 
Fibonacci number theory gives that Fi 


1  1  5 
 nh 
5  2 
22/22

5

h 2

1

 h  O(lnn)

2




Slide 16

§3 The Search Tree ADT -- Binary Search Trees
1. Definition
【Definition】A binary search tree is a binary tree. It may be
(1)
(2)
(3)
(4)

empty. If it is not empty, it satisfies the following properties:
Every node has a key which is an integer, and the keys are
distinct.
The keys in a nonempty left subtree must be smaller than
the key in the root of the subtree.
The keys in a nonempty right subtree must be larger than
the key in the root of the subtree.
The left and right subtrees are also binary search trees.

30

5
2

1/22

60

40

20
70

65

15
80

12

10

25
22

§3 Binary Search Trees

2. ADT
Objects: A finite ordered list with zero or more elements.
Operations:

 SearchTree MakeEmpty( SearchTree T );
 Position Find( ElementType X, SearchTree T );
 Position FindMin( SearchTree T );
 Position FindMax( SearchTree T );
 SearchTree Insert( ElementType X, SearchTree T );
 SearchTree Delete( ElementType X, SearchTree T );
 ElementType Retrieve( Position P );

2/22

§3 Binary Search Trees

3. Implementations

 Find

Must this test
be performed first?

Position Find( ElementType X, SearchTree T )
{
if ( T == NULL )
These are
return NULL; /* not found in an empty tree */
tail recursions.
if ( X < T->Element ) /* if smaller than root */
return Find( X, T->Left ); /* search left subtree */
else
if ( X > T->Element ) /* if larger than root */
return Find( X, T->Right ); /* search right subtree */
else /* if X == root */
return T; /* found */
}
T( N ) = S ( N ) = O( d ) where d is the depth of X

3/22

§3 Binary Search Trees

Position Iter_Find( ElementType X, SearchTree T )
{
/* iterative version of Find */
while ( T ) {
if ( X == T->Element )
return T ; /* found */
if ( X < T->Element )
T = T->Left ; /*move down along left path */
else
T = T-> Right ; /* move down along right path */
} /* end while-loop */
return NULL ; /* not found */
}

4/22



FindMin

§3 Binary Search Trees

Position FindMin( SearchTree T )
T( N ) = O ( d )
{
if ( T == NULL )
return NULL; /* not found in an empty tree */
else
if ( T->Left == NULL ) return T; /* found left most */
else return FindMin( T->Left ); /* keep moving to left */
}

 FindMax
Position FindMax( SearchTree T )
T( N ) = O ( d )
{
if ( T != NULL )
while ( T->Right != NULL )
T = T->Right; /* keep moving to find right most */
return T; /* return NULL or the right most */
}

5/22

§3 Binary Search Trees

 Insert
Sketch of the idea:
Insert 80

30
5
2

40
25 35

Insert 35

Insert 25

6/22

 check if 80 is already in the tree
 80 > 40, so it must be the right child
80

of 40

Thisifis35
theis last
nodein the tree
 check
already
we encounter
 35search
< 40, so it must be the left child of 40
when
for the key number.
It will be the parent
 check if 25 is already in the tree
of the new node.
 25 > 5, so it must be the right child of 5

§3 Binary Search Trees
SearchTree Insert( ElementType X, SearchTree T )
{
if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct TreeNode ) );
if ( T == NULL )
FatalError( "Out of space!!!" );
else {
T->Element = X;
How would you
T->Left = T->Right = NULL; }
Handle
T(
N ) = duplicated
O(d)
} /* End creating a one-node tree */
Keys?
else /* If there is a tree */
if ( X < T->Element )
T->Left = Insert( X, T->Left );
else
if ( X > T->Element )
T->Right = Insert( X, T->Right );
/* Else X is in the tree already; we'll do nothing */
return T; /* Do not forget this line!! */
}

7/22

§3 Binary Search Trees

 Delete

 Delete a leaf nodeNote:
: Reset
its kinds
parentoflink
to NULL.
These
nodes
have: degree
atthe
most
1. by its single child.
 Delete a degree 1 node
Replace
node
 Delete a degree 2 node :

 Replace the node by the largest one in its left subtree or
the smallest one in its right subtree.
 Delete the replacing node from the subtree.

〖Example〗 Delete 60

40
20

Solution 1: reset left subtree.

10

60
55
30

50 70

Solution 2: reset right subtree.

45

55
52
52

8/22

§3 Binary Search Trees
SearchTree Delete( ElementType X, SearchTree T )
{ Position TmpCell;
if ( T == NULL ) Error( "Element not found" );
else if ( X < T->Element ) /* Go left */
T->Left = Delete( X, T->Left );
else if ( X > T->Element ) /* Go right */
T->Right = Delete( X, T->Right );
else /* Found element to be deleted */
if ( T->Left && T->Right ) { /* Two children */
/* Replace with smallest in right subtree */
TmpCell = FindMin( T->Right );
T->Element = TmpCell->Element;
T->Right = Delete( T->Element, T->Right ); } /* End if */
else { /* One or zero child */
TmpCell = T;
if ( T->Left == NULL ) /* Also handles 0 child */
T = T->Right;
else if ( T->Right == NULL ) T = T->Left;
free( TmpCell ); } /* End else 1 or 0 child */
return T;
T( N ) = O ( h ) where h is the height of the tree
}
9/22

§3 Binary Search Trees

Note:
If there are not many deletions, then lazy deletion
may be employed: add a flag field to each node, to mark
if a node is active or is deleted. Therefore we can delete
a node without actually freeing the space of that node.
If a deleted key is reinserted, we won’t have to call
malloc again.

While the number of deleted nodes
is the same as the number of active nodes
in the tree, will it seriously affect
the efficiency of the operations?

10/22

§3 Binary Search Trees

4. Average-Case Analysis
Question: Place n elements in a binary search tree. How
high can this tree be?

Answer: The height depends on the order of insertion.
〖Example〗 Given elements 1, 2, 3, 4, 5, 6, 7. Insert
them into a binary search tree in the orders:
4, 2, 1, 3, 6, 5, 7
and
1, 2, 3, 4, 5, 6, 7
4
2
1

6
3

5

h=2

11/22

h=6
7

§3 Binary Search Trees

【Definition】The internal path length for a tree of N nodes
N

is defined to be:

D( N )   d ( i ) , D(1)  0
i 1

where d( i ) is the
depth of work:
node i.
Home

【Theorem】 Assume that all binary search trees are equally
p.139 4.42
likely. Then the average D(N) (taken over all possible
Isomorphic
Trees
insertion sequences)
is O(N log
N). Thus the expected
depth of any node is O(log N).

p.140 4.45
D( N ) = D( i ) + D( N  i  1 ) + N  1
Threaded Trees

Proof:
Since all subtree sizes are
equally likely, the average
i nodes
value of both D( i ) and
N 1
D( N  i  1 ) is [ j  0 D( j )] N .

D( N ) 
12/22

2
N

[ j 0 D( j )]  N  1 =
N 1

root
+1
N  i  1 nodes

p.212-213

= O(N log N)

§4 AVL Trees
Target : Speed up searching (with insertion and
deletion)

root

Tool : Binary search trees
small

large

Problem : Although Tp = O( height ), but the
height can be as bad as O( N ).

13/22

§4 AVL Trees

〖Example〗 3 binary search trees obtained for the months
of the year
Jan

Average search time = ?3.5

Feb

Mar

Apr

June
Aug

May

July

Sept

Dec

Oct

Entered from Jan to Dec

AST = 6.5

Nov

July
Feb

Aug
Apr

May

Jan
Dec

Mar
June

A balanced tree
14/22

What if the months
are entered in
alphabetical order?

Average search time = ?3.1
Oct

Nov

Sept

§4 AVL Trees

Adelson-Velskii-Landis (AVL) Trees (1962)
【Definition】An empty binary tree is height balanced. If T is a
nonempty binary tree with TL and TR as its left and right
subtrees, then T is height balanced iff
(1) TL and TR are height balanced, and
The height of an empty tree
(2) | hL  hR |  1 where hL and hisR defined
are thetoheights
be –1. of TL and TR ,
respectively.

【Definition】The balance factor BF( node ) = hL  hR . In an
AVL tree, BF( node ) = 1, 0, or 1.
4

3
2
1
15/22

5

5

2
6

1
7

8
4 7

3

7

2
1

8
4

3

5

§4 AVL Trees

〖Example〗 Input the months

Mar

May

1
2
0

Mar

Nov
1
2
01
0

1
0

May

Single rotation

May
0

00

00

Mar

Nov

Nov

 The trouble maker Nov is in the right subtree’s right
subtree of the trouble finder Mar. Hence it is called an
RR rotation.
A is not necessarily
In general:
the root of the tree
1

A

RR
0

16/22

1

BR

B
BL

0

RR

BR

B

A

Rotation

AL

AL
BL

A

Insertion

B

0

2

BR
AL

BL

Aug

§4 AVL Trees

Apr
2
1
01
12

1
2
01
1

LL

May
210

00

Mar

Nov

1
010

Rotation

May
00

Aug

Nov

10

0

0

Aug

Apr

Mar

0

Apr
In general:
1
0

2

LL

A

1

Insertion

B

A

17/22

BR

LL

B
AR
BL

B

Rotation

AR
BL

0

BR

0

A
BL
BR

AR

§4 AVL Trees

Jan

21
2
1
01

Double Rotation

1
2
01
0

May

1
010

00

Aug

1
010

Nov

0

10

Apr

Mar

Aug

LR

0

Jan

Mar

1
0

May

0

0

Apr

Jan

0

Nov

Rotation

In general:
1
0

B

A

CL

Insertion

1

B

0

C
BL

2

LR

A

BL

CL

18/22

0 or 1

C

1 or 0

B

AR
CR

OR

0

Rotation

1

C

AR
CR

LR

BL

A
CL

CR
OR

AR

Dec

July

§4 AVL Trees

Feb

1
2
01
21

Mar

1
2
10

Aug

1
0

May

0

01

Apr

Jan

1
0

Nov

Dec

10

01
10

Aug

Jan

1
0

May
0

Nov

0

0

Apr

Feb

July

2

RL

July
0

Mar

1
02
1
0

Rotation
0

0

Dec

1
2
01
1

RL

0

Feb
In general:
1

A
0

RL
0

Insertion

B

1

C

AL
CL

A

CR

CL

19/22

B

0 or 1

C

1 or 0

A
CR

OR

0

Rotation

C

AL
BR

1

BR
AL

B
CL

CR
OR

BR

June

Oct

§4 AVL Trees

Sept
1
0

1
0 2
1
01
21

Jan
Mar
Jan
1
1
12
1
0 1
00
02
1
0
1
1
12
1
0
0 1
Dec
Mar
May
Dec Dec
Mar

1 10

1 Aug
Aug

Aug

0 0

0 Apr
Apr

Apr

0

0

Feb
Feb0
Feb

01
10 1
1
Jan

July
July

1
00

0 July
June

June

2
10

1
0
May
Nov
Nov

1
0 1
0
Nov 0
Oct
May
0
0

June

Note: Several bf’s
might be changed even if
we don’t need to reconstruct
the tree.

Oct 0
Sept

Another option is to keep a height field for each node.

20/22

§4 AVL Trees
AvlTree Insert( ElementType X, AvlTree T )
{ if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct AvlNode ) );
if ( T == NULL ) FatalError( "Out of space!!!" );
else { T->Element = X; T->Height = 0; T->Left = T->Right = NULL; }
} /* End creating a one-node tree */
else if ( X < T->Element ) { /* handle left insertion */
T->Left = Insert( X, T->Left );
if ( Height( T->Left ) - Height( T->Right ) == 2 ) /* not balanced */
if ( X < T->Left->Element ) /* LL Rotation */
T = SingleRotateWithLeft( T );
else /* LR Rotation */
T = DoubleRotateWithLeft( T ); } /* End left */
else if( X > T->Element ) { /* handle right insertion */
T->Right = Insert( X, T->Right );
if ( Height( T->Right ) - Height( T->Left ) == 2 ) /* not balanced */
if ( X > T->Right->Element ) /* RR Rotation */
T = SingleRotateWithRight( T );
else /* RL Rotation */
T = DoubleRotateWithRight( T ); } /* End right */
/* Else X is in the tree already; we'll do nothing */
T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
return T;
}

Home work:

p.136 4.16
Create an AVL Tree
p.136 4.22
Double Rotation

21/22

§4 AVL Trees

Let nh be the minimum number of nodes in a height balanced tree of
height h. Then the tree must look like

A
h2

A
h1

last question:
OROne
h1
h2  nh = nh1 + nh2 + 1

Obviously we have Tp = O( h )
where h is the height of the tree.
But h = ?

Fibonacci numbers:
F0 = 0, F1 = 1, Fi = Fi1 + Fi2 for i > 1
 nh = Fh+2  1, for h  0
i


1  1 5 
Fibonacci number theory gives that Fi 


1  1  5 
 nh 
5  2 
22/22

5

h 2

1

 h  O(lnn)

2




Slide 17

§3 The Search Tree ADT -- Binary Search Trees
1. Definition
【Definition】A binary search tree is a binary tree. It may be
(1)
(2)
(3)
(4)

empty. If it is not empty, it satisfies the following properties:
Every node has a key which is an integer, and the keys are
distinct.
The keys in a nonempty left subtree must be smaller than
the key in the root of the subtree.
The keys in a nonempty right subtree must be larger than
the key in the root of the subtree.
The left and right subtrees are also binary search trees.

30

5
2

1/22

60

40

20
70

65

15
80

12

10

25
22

§3 Binary Search Trees

2. ADT
Objects: A finite ordered list with zero or more elements.
Operations:

 SearchTree MakeEmpty( SearchTree T );
 Position Find( ElementType X, SearchTree T );
 Position FindMin( SearchTree T );
 Position FindMax( SearchTree T );
 SearchTree Insert( ElementType X, SearchTree T );
 SearchTree Delete( ElementType X, SearchTree T );
 ElementType Retrieve( Position P );

2/22

§3 Binary Search Trees

3. Implementations

 Find

Must this test
be performed first?

Position Find( ElementType X, SearchTree T )
{
if ( T == NULL )
These are
return NULL; /* not found in an empty tree */
tail recursions.
if ( X < T->Element ) /* if smaller than root */
return Find( X, T->Left ); /* search left subtree */
else
if ( X > T->Element ) /* if larger than root */
return Find( X, T->Right ); /* search right subtree */
else /* if X == root */
return T; /* found */
}
T( N ) = S ( N ) = O( d ) where d is the depth of X

3/22

§3 Binary Search Trees

Position Iter_Find( ElementType X, SearchTree T )
{
/* iterative version of Find */
while ( T ) {
if ( X == T->Element )
return T ; /* found */
if ( X < T->Element )
T = T->Left ; /*move down along left path */
else
T = T-> Right ; /* move down along right path */
} /* end while-loop */
return NULL ; /* not found */
}

4/22



FindMin

§3 Binary Search Trees

Position FindMin( SearchTree T )
T( N ) = O ( d )
{
if ( T == NULL )
return NULL; /* not found in an empty tree */
else
if ( T->Left == NULL ) return T; /* found left most */
else return FindMin( T->Left ); /* keep moving to left */
}

 FindMax
Position FindMax( SearchTree T )
T( N ) = O ( d )
{
if ( T != NULL )
while ( T->Right != NULL )
T = T->Right; /* keep moving to find right most */
return T; /* return NULL or the right most */
}

5/22

§3 Binary Search Trees

 Insert
Sketch of the idea:
Insert 80

30
5
2

40
25 35

Insert 35

Insert 25

6/22

 check if 80 is already in the tree
 80 > 40, so it must be the right child
80

of 40

Thisifis35
theis last
nodein the tree
 check
already
we encounter
 35search
< 40, so it must be the left child of 40
when
for the key number.
It will be the parent
 check if 25 is already in the tree
of the new node.
 25 > 5, so it must be the right child of 5

§3 Binary Search Trees
SearchTree Insert( ElementType X, SearchTree T )
{
if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct TreeNode ) );
if ( T == NULL )
FatalError( "Out of space!!!" );
else {
T->Element = X;
How would you
T->Left = T->Right = NULL; }
Handle
T(
N ) = duplicated
O(d)
} /* End creating a one-node tree */
Keys?
else /* If there is a tree */
if ( X < T->Element )
T->Left = Insert( X, T->Left );
else
if ( X > T->Element )
T->Right = Insert( X, T->Right );
/* Else X is in the tree already; we'll do nothing */
return T; /* Do not forget this line!! */
}

7/22

§3 Binary Search Trees

 Delete

 Delete a leaf nodeNote:
: Reset
its kinds
parentoflink
to NULL.
These
nodes
have: degree
atthe
most
1. by its single child.
 Delete a degree 1 node
Replace
node
 Delete a degree 2 node :

 Replace the node by the largest one in its left subtree or
the smallest one in its right subtree.
 Delete the replacing node from the subtree.

〖Example〗 Delete 60

40
20

Solution 1: reset left subtree.

10

60
55
30

50 70

Solution 2: reset right subtree.

45

55
52
52

8/22

§3 Binary Search Trees
SearchTree Delete( ElementType X, SearchTree T )
{ Position TmpCell;
if ( T == NULL ) Error( "Element not found" );
else if ( X < T->Element ) /* Go left */
T->Left = Delete( X, T->Left );
else if ( X > T->Element ) /* Go right */
T->Right = Delete( X, T->Right );
else /* Found element to be deleted */
if ( T->Left && T->Right ) { /* Two children */
/* Replace with smallest in right subtree */
TmpCell = FindMin( T->Right );
T->Element = TmpCell->Element;
T->Right = Delete( T->Element, T->Right ); } /* End if */
else { /* One or zero child */
TmpCell = T;
if ( T->Left == NULL ) /* Also handles 0 child */
T = T->Right;
else if ( T->Right == NULL ) T = T->Left;
free( TmpCell ); } /* End else 1 or 0 child */
return T;
T( N ) = O ( h ) where h is the height of the tree
}
9/22

§3 Binary Search Trees

Note:
If there are not many deletions, then lazy deletion
may be employed: add a flag field to each node, to mark
if a node is active or is deleted. Therefore we can delete
a node without actually freeing the space of that node.
If a deleted key is reinserted, we won’t have to call
malloc again.

While the number of deleted nodes
is the same as the number of active nodes
in the tree, will it seriously affect
the efficiency of the operations?

10/22

§3 Binary Search Trees

4. Average-Case Analysis
Question: Place n elements in a binary search tree. How
high can this tree be?

Answer: The height depends on the order of insertion.
〖Example〗 Given elements 1, 2, 3, 4, 5, 6, 7. Insert
them into a binary search tree in the orders:
4, 2, 1, 3, 6, 5, 7
and
1, 2, 3, 4, 5, 6, 7
4
2
1

6
3

5

h=2

11/22

h=6
7

§3 Binary Search Trees

【Definition】The internal path length for a tree of N nodes
N

is defined to be:

D( N )   d ( i ) , D(1)  0
i 1

where d( i ) is the
depth of work:
node i.
Home

【Theorem】 Assume that all binary search trees are equally
p.139 4.42
likely. Then the average D(N) (taken over all possible
Isomorphic
Trees
insertion sequences)
is O(N log
N). Thus the expected
depth of any node is O(log N).

p.140 4.45
D( N ) = D( i ) + D( N  i  1 ) + N  1
Threaded Trees

Proof:
Since all subtree sizes are
equally likely, the average
i nodes
value of both D( i ) and
N 1
D( N  i  1 ) is [ j  0 D( j )] N .

D( N ) 
12/22

2
N

[ j 0 D( j )]  N  1 =
N 1

root
+1
N  i  1 nodes

p.212-213

= O(N log N)

§4 AVL Trees
Target : Speed up searching (with insertion and
deletion)

root

Tool : Binary search trees
small

large

Problem : Although Tp = O( height ), but the
height can be as bad as O( N ).

13/22

§4 AVL Trees

〖Example〗 3 binary search trees obtained for the months
of the year
Jan

Average search time = ?3.5

Feb

Mar

Apr

June
Aug

May

July

Sept

Dec

Oct

Entered from Jan to Dec

AST = 6.5

Nov

July
Feb

Aug
Apr

May

Jan
Dec

Mar
June

A balanced tree
14/22

What if the months
are entered in
alphabetical order?

Average search time = ?3.1
Oct

Nov

Sept

§4 AVL Trees

Adelson-Velskii-Landis (AVL) Trees (1962)
【Definition】An empty binary tree is height balanced. If T is a
nonempty binary tree with TL and TR as its left and right
subtrees, then T is height balanced iff
(1) TL and TR are height balanced, and
The height of an empty tree
(2) | hL  hR |  1 where hL and hisR defined
are thetoheights
be –1. of TL and TR ,
respectively.

【Definition】The balance factor BF( node ) = hL  hR . In an
AVL tree, BF( node ) = 1, 0, or 1.
4

3
2
1
15/22

5

5

2
6

1
7

8
4 7

3

7

2
1

8
4

3

5

§4 AVL Trees

〖Example〗 Input the months

Mar

May

1
2
0

Mar

Nov
1
2
01
0

1
0

May

Single rotation

May
0

00

00

Mar

Nov

Nov

 The trouble maker Nov is in the right subtree’s right
subtree of the trouble finder Mar. Hence it is called an
RR rotation.
A is not necessarily
In general:
the root of the tree
1

A

RR
0

16/22

1

BR

B
BL

0

RR

BR

B

A

Rotation

AL

AL
BL

A

Insertion

B

0

2

BR
AL

BL

Aug

§4 AVL Trees

Apr
2
1
01
12

1
2
01
1

LL

May
210

00

Mar

Nov

1
010

Rotation

May
00

Aug

Nov

10

0

0

Aug

Apr

Mar

0

Apr
In general:
1
0

2

LL

A

1

Insertion

B

A

17/22

BR

LL

B
AR
BL

B

Rotation

AR
BL

0

BR

0

A
BL
BR

AR

§4 AVL Trees

Jan

21
2
1
01

Double Rotation

1
2
01
0

May

1
010

00

Aug

1
010

Nov

0

10

Apr

Mar

Aug

LR

0

Jan

Mar

1
0

May

0

0

Apr

Jan

0

Nov

Rotation

In general:
1
0

B

A

CL

Insertion

1

B

0

C
BL

2

LR

A

BL

CL

18/22

0 or 1

C

1 or 0

B

AR
CR

OR

0

Rotation

1

C

AR
CR

LR

BL

A
CL

CR
OR

AR

Dec

July

§4 AVL Trees

Feb

1
2
01
21

Mar

1
2
10

Aug

1
0

May

0

01

Apr

Jan

1
0

Nov

Dec

10

01
10

Aug

Jan

1
0

May
0

Nov

0

0

Apr

Feb

July

2

RL

July
0

Mar

1
02
1
0

Rotation
0

0

Dec

1
2
01
1

RL

0

Feb
In general:
1

A
0

RL
0

Insertion

B

1

C

AL
CL

A

CR

CL

19/22

B

0 or 1

C

1 or 0

A
CR

OR

0

Rotation

C

AL
BR

1

BR
AL

B
CL

CR
OR

BR

June

Oct

§4 AVL Trees

Sept
1
0

1
0 2
1
01
21

Jan
Mar
Jan
1
1
12
1
0 1
00
02
1
0
1
1
12
1
0
0 1
Dec
Mar
May
Dec Dec
Mar

1 10

1 Aug
Aug

Aug

0 0

0 Apr
Apr

Apr

0

0

Feb
Feb0
Feb

01
10 1
1
Jan

July
July

1
00

0 July
June

June

2
10

1
0
May
Nov
Nov

1
0 1
0
Nov 0
Oct
May
0
0

June

Note: Several bf’s
might be changed even if
we don’t need to reconstruct
the tree.

Oct 0
Sept

Another option is to keep a height field for each node.

20/22

§4 AVL Trees
AvlTree Insert( ElementType X, AvlTree T )
{ if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct AvlNode ) );
if ( T == NULL ) FatalError( "Out of space!!!" );
else { T->Element = X; T->Height = 0; T->Left = T->Right = NULL; }
} /* End creating a one-node tree */
else if ( X < T->Element ) { /* handle left insertion */
T->Left = Insert( X, T->Left );
if ( Height( T->Left ) - Height( T->Right ) == 2 ) /* not balanced */
if ( X < T->Left->Element ) /* LL Rotation */
T = SingleRotateWithLeft( T );
else /* LR Rotation */
T = DoubleRotateWithLeft( T ); } /* End left */
else if( X > T->Element ) { /* handle right insertion */
T->Right = Insert( X, T->Right );
if ( Height( T->Right ) - Height( T->Left ) == 2 ) /* not balanced */
if ( X > T->Right->Element ) /* RR Rotation */
T = SingleRotateWithRight( T );
else /* RL Rotation */
T = DoubleRotateWithRight( T ); } /* End right */
/* Else X is in the tree already; we'll do nothing */
T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
return T;
}

Home work:

p.136 4.16
Create an AVL Tree
p.136 4.22
Double Rotation

21/22

§4 AVL Trees

Let nh be the minimum number of nodes in a height balanced tree of
height h. Then the tree must look like

A
h2

A
h1

last question:
OROne
h1
h2  nh = nh1 + nh2 + 1

Obviously we have Tp = O( h )
where h is the height of the tree.
But h = ?

Fibonacci numbers:
F0 = 0, F1 = 1, Fi = Fi1 + Fi2 for i > 1
 nh = Fh+2  1, for h  0
i


1  1 5 
Fibonacci number theory gives that Fi 


1  1  5 
 nh 
5  2 
22/22

5

h 2

1

 h  O(lnn)

2




Slide 18

§3 The Search Tree ADT -- Binary Search Trees
1. Definition
【Definition】A binary search tree is a binary tree. It may be
(1)
(2)
(3)
(4)

empty. If it is not empty, it satisfies the following properties:
Every node has a key which is an integer, and the keys are
distinct.
The keys in a nonempty left subtree must be smaller than
the key in the root of the subtree.
The keys in a nonempty right subtree must be larger than
the key in the root of the subtree.
The left and right subtrees are also binary search trees.

30

5
2

1/22

60

40

20
70

65

15
80

12

10

25
22

§3 Binary Search Trees

2. ADT
Objects: A finite ordered list with zero or more elements.
Operations:

 SearchTree MakeEmpty( SearchTree T );
 Position Find( ElementType X, SearchTree T );
 Position FindMin( SearchTree T );
 Position FindMax( SearchTree T );
 SearchTree Insert( ElementType X, SearchTree T );
 SearchTree Delete( ElementType X, SearchTree T );
 ElementType Retrieve( Position P );

2/22

§3 Binary Search Trees

3. Implementations

 Find

Must this test
be performed first?

Position Find( ElementType X, SearchTree T )
{
if ( T == NULL )
These are
return NULL; /* not found in an empty tree */
tail recursions.
if ( X < T->Element ) /* if smaller than root */
return Find( X, T->Left ); /* search left subtree */
else
if ( X > T->Element ) /* if larger than root */
return Find( X, T->Right ); /* search right subtree */
else /* if X == root */
return T; /* found */
}
T( N ) = S ( N ) = O( d ) where d is the depth of X

3/22

§3 Binary Search Trees

Position Iter_Find( ElementType X, SearchTree T )
{
/* iterative version of Find */
while ( T ) {
if ( X == T->Element )
return T ; /* found */
if ( X < T->Element )
T = T->Left ; /*move down along left path */
else
T = T-> Right ; /* move down along right path */
} /* end while-loop */
return NULL ; /* not found */
}

4/22



FindMin

§3 Binary Search Trees

Position FindMin( SearchTree T )
T( N ) = O ( d )
{
if ( T == NULL )
return NULL; /* not found in an empty tree */
else
if ( T->Left == NULL ) return T; /* found left most */
else return FindMin( T->Left ); /* keep moving to left */
}

 FindMax
Position FindMax( SearchTree T )
T( N ) = O ( d )
{
if ( T != NULL )
while ( T->Right != NULL )
T = T->Right; /* keep moving to find right most */
return T; /* return NULL or the right most */
}

5/22

§3 Binary Search Trees

 Insert
Sketch of the idea:
Insert 80

30
5
2

40
25 35

Insert 35

Insert 25

6/22

 check if 80 is already in the tree
 80 > 40, so it must be the right child
80

of 40

Thisifis35
theis last
nodein the tree
 check
already
we encounter
 35search
< 40, so it must be the left child of 40
when
for the key number.
It will be the parent
 check if 25 is already in the tree
of the new node.
 25 > 5, so it must be the right child of 5

§3 Binary Search Trees
SearchTree Insert( ElementType X, SearchTree T )
{
if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct TreeNode ) );
if ( T == NULL )
FatalError( "Out of space!!!" );
else {
T->Element = X;
How would you
T->Left = T->Right = NULL; }
Handle
T(
N ) = duplicated
O(d)
} /* End creating a one-node tree */
Keys?
else /* If there is a tree */
if ( X < T->Element )
T->Left = Insert( X, T->Left );
else
if ( X > T->Element )
T->Right = Insert( X, T->Right );
/* Else X is in the tree already; we'll do nothing */
return T; /* Do not forget this line!! */
}

7/22

§3 Binary Search Trees

 Delete

 Delete a leaf nodeNote:
: Reset
its kinds
parentoflink
to NULL.
These
nodes
have: degree
atthe
most
1. by its single child.
 Delete a degree 1 node
Replace
node
 Delete a degree 2 node :

 Replace the node by the largest one in its left subtree or
the smallest one in its right subtree.
 Delete the replacing node from the subtree.

〖Example〗 Delete 60

40
20

Solution 1: reset left subtree.

10

60
55
30

50 70

Solution 2: reset right subtree.

45

55
52
52

8/22

§3 Binary Search Trees
SearchTree Delete( ElementType X, SearchTree T )
{ Position TmpCell;
if ( T == NULL ) Error( "Element not found" );
else if ( X < T->Element ) /* Go left */
T->Left = Delete( X, T->Left );
else if ( X > T->Element ) /* Go right */
T->Right = Delete( X, T->Right );
else /* Found element to be deleted */
if ( T->Left && T->Right ) { /* Two children */
/* Replace with smallest in right subtree */
TmpCell = FindMin( T->Right );
T->Element = TmpCell->Element;
T->Right = Delete( T->Element, T->Right ); } /* End if */
else { /* One or zero child */
TmpCell = T;
if ( T->Left == NULL ) /* Also handles 0 child */
T = T->Right;
else if ( T->Right == NULL ) T = T->Left;
free( TmpCell ); } /* End else 1 or 0 child */
return T;
T( N ) = O ( h ) where h is the height of the tree
}
9/22

§3 Binary Search Trees

Note:
If there are not many deletions, then lazy deletion
may be employed: add a flag field to each node, to mark
if a node is active or is deleted. Therefore we can delete
a node without actually freeing the space of that node.
If a deleted key is reinserted, we won’t have to call
malloc again.

While the number of deleted nodes
is the same as the number of active nodes
in the tree, will it seriously affect
the efficiency of the operations?

10/22

§3 Binary Search Trees

4. Average-Case Analysis
Question: Place n elements in a binary search tree. How
high can this tree be?

Answer: The height depends on the order of insertion.
〖Example〗 Given elements 1, 2, 3, 4, 5, 6, 7. Insert
them into a binary search tree in the orders:
4, 2, 1, 3, 6, 5, 7
and
1, 2, 3, 4, 5, 6, 7
4
2
1

6
3

5

h=2

11/22

h=6
7

§3 Binary Search Trees

【Definition】The internal path length for a tree of N nodes
N

is defined to be:

D( N )   d ( i ) , D(1)  0
i 1

where d( i ) is the
depth of work:
node i.
Home

【Theorem】 Assume that all binary search trees are equally
p.139 4.42
likely. Then the average D(N) (taken over all possible
Isomorphic
Trees
insertion sequences)
is O(N log
N). Thus the expected
depth of any node is O(log N).

p.140 4.45
D( N ) = D( i ) + D( N  i  1 ) + N  1
Threaded Trees

Proof:
Since all subtree sizes are
equally likely, the average
i nodes
value of both D( i ) and
N 1
D( N  i  1 ) is [ j  0 D( j )] N .

D( N ) 
12/22

2
N

[ j 0 D( j )]  N  1 =
N 1

root
+1
N  i  1 nodes

p.212-213

= O(N log N)

§4 AVL Trees
Target : Speed up searching (with insertion and
deletion)

root

Tool : Binary search trees
small

large

Problem : Although Tp = O( height ), but the
height can be as bad as O( N ).

13/22

§4 AVL Trees

〖Example〗 3 binary search trees obtained for the months
of the year
Jan

Average search time = ?3.5

Feb

Mar

Apr

June
Aug

May

July

Sept

Dec

Oct

Entered from Jan to Dec

AST = 6.5

Nov

July
Feb

Aug
Apr

May

Jan
Dec

Mar
June

A balanced tree
14/22

What if the months
are entered in
alphabetical order?

Average search time = ?3.1
Oct

Nov

Sept

§4 AVL Trees

Adelson-Velskii-Landis (AVL) Trees (1962)
【Definition】An empty binary tree is height balanced. If T is a
nonempty binary tree with TL and TR as its left and right
subtrees, then T is height balanced iff
(1) TL and TR are height balanced, and
The height of an empty tree
(2) | hL  hR |  1 where hL and hisR defined
are thetoheights
be –1. of TL and TR ,
respectively.

【Definition】The balance factor BF( node ) = hL  hR . In an
AVL tree, BF( node ) = 1, 0, or 1.
4

3
2
1
15/22

5

5

2
6

1
7

8
4 7

3

7

2
1

8
4

3

5

§4 AVL Trees

〖Example〗 Input the months

Mar

May

1
2
0

Mar

Nov
1
2
01
0

1
0

May

Single rotation

May
0

00

00

Mar

Nov

Nov

 The trouble maker Nov is in the right subtree’s right
subtree of the trouble finder Mar. Hence it is called an
RR rotation.
A is not necessarily
In general:
the root of the tree
1

A

RR
0

16/22

1

BR

B
BL

0

RR

BR

B

A

Rotation

AL

AL
BL

A

Insertion

B

0

2

BR
AL

BL

Aug

§4 AVL Trees

Apr
2
1
01
12

1
2
01
1

LL

May
210

00

Mar

Nov

1
010

Rotation

May
00

Aug

Nov

10

0

0

Aug

Apr

Mar

0

Apr
In general:
1
0

2

LL

A

1

Insertion

B

A

17/22

BR

LL

B
AR
BL

B

Rotation

AR
BL

0

BR

0

A
BL
BR

AR

§4 AVL Trees

Jan

21
2
1
01

Double Rotation

1
2
01
0

May

1
010

00

Aug

1
010

Nov

0

10

Apr

Mar

Aug

LR

0

Jan

Mar

1
0

May

0

0

Apr

Jan

0

Nov

Rotation

In general:
1
0

B

A

CL

Insertion

1

B

0

C
BL

2

LR

A

BL

CL

18/22

0 or 1

C

1 or 0

B

AR
CR

OR

0

Rotation

1

C

AR
CR

LR

BL

A
CL

CR
OR

AR

Dec

July

§4 AVL Trees

Feb

1
2
01
21

Mar

1
2
10

Aug

1
0

May

0

01

Apr

Jan

1
0

Nov

Dec

10

01
10

Aug

Jan

1
0

May
0

Nov

0

0

Apr

Feb

July

2

RL

July
0

Mar

1
02
1
0

Rotation
0

0

Dec

1
2
01
1

RL

0

Feb
In general:
1

A
0

RL
0

Insertion

B

1

C

AL
CL

A

CR

CL

19/22

B

0 or 1

C

1 or 0

A
CR

OR

0

Rotation

C

AL
BR

1

BR
AL

B
CL

CR
OR

BR

June

Oct

§4 AVL Trees

Sept
1
0

1
0 2
1
01
21

Jan
Mar
Jan
1
1
12
1
0 1
00
02
1
0
1
1
12
1
0
0 1
Dec
Mar
May
Dec Dec
Mar

1 10

1 Aug
Aug

Aug

0 0

0 Apr
Apr

Apr

0

0

Feb
Feb0
Feb

01
10 1
1
Jan

July
July

1
00

0 July
June

June

2
10

1
0
May
Nov
Nov

1
0 1
0
Nov 0
Oct
May
0
0

June

Note: Several bf’s
might be changed even if
we don’t need to reconstruct
the tree.

Oct 0
Sept

Another option is to keep a height field for each node.

20/22

§4 AVL Trees
AvlTree Insert( ElementType X, AvlTree T )
{ if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct AvlNode ) );
if ( T == NULL ) FatalError( "Out of space!!!" );
else { T->Element = X; T->Height = 0; T->Left = T->Right = NULL; }
} /* End creating a one-node tree */
else if ( X < T->Element ) { /* handle left insertion */
T->Left = Insert( X, T->Left );
if ( Height( T->Left ) - Height( T->Right ) == 2 ) /* not balanced */
if ( X < T->Left->Element ) /* LL Rotation */
T = SingleRotateWithLeft( T );
else /* LR Rotation */
T = DoubleRotateWithLeft( T ); } /* End left */
else if( X > T->Element ) { /* handle right insertion */
T->Right = Insert( X, T->Right );
if ( Height( T->Right ) - Height( T->Left ) == 2 ) /* not balanced */
if ( X > T->Right->Element ) /* RR Rotation */
T = SingleRotateWithRight( T );
else /* RL Rotation */
T = DoubleRotateWithRight( T ); } /* End right */
/* Else X is in the tree already; we'll do nothing */
T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
return T;
}

Home work:

p.136 4.16
Create an AVL Tree
p.136 4.22
Double Rotation

21/22

§4 AVL Trees

Let nh be the minimum number of nodes in a height balanced tree of
height h. Then the tree must look like

A
h2

A
h1

last question:
OROne
h1
h2  nh = nh1 + nh2 + 1

Obviously we have Tp = O( h )
where h is the height of the tree.
But h = ?

Fibonacci numbers:
F0 = 0, F1 = 1, Fi = Fi1 + Fi2 for i > 1
 nh = Fh+2  1, for h  0
i


1  1 5 
Fibonacci number theory gives that Fi 


1  1  5 
 nh 
5  2 
22/22

5

h 2

1

 h  O(lnn)

2




Slide 19

§3 The Search Tree ADT -- Binary Search Trees
1. Definition
【Definition】A binary search tree is a binary tree. It may be
(1)
(2)
(3)
(4)

empty. If it is not empty, it satisfies the following properties:
Every node has a key which is an integer, and the keys are
distinct.
The keys in a nonempty left subtree must be smaller than
the key in the root of the subtree.
The keys in a nonempty right subtree must be larger than
the key in the root of the subtree.
The left and right subtrees are also binary search trees.

30

5
2

1/22

60

40

20
70

65

15
80

12

10

25
22

§3 Binary Search Trees

2. ADT
Objects: A finite ordered list with zero or more elements.
Operations:

 SearchTree MakeEmpty( SearchTree T );
 Position Find( ElementType X, SearchTree T );
 Position FindMin( SearchTree T );
 Position FindMax( SearchTree T );
 SearchTree Insert( ElementType X, SearchTree T );
 SearchTree Delete( ElementType X, SearchTree T );
 ElementType Retrieve( Position P );

2/22

§3 Binary Search Trees

3. Implementations

 Find

Must this test
be performed first?

Position Find( ElementType X, SearchTree T )
{
if ( T == NULL )
These are
return NULL; /* not found in an empty tree */
tail recursions.
if ( X < T->Element ) /* if smaller than root */
return Find( X, T->Left ); /* search left subtree */
else
if ( X > T->Element ) /* if larger than root */
return Find( X, T->Right ); /* search right subtree */
else /* if X == root */
return T; /* found */
}
T( N ) = S ( N ) = O( d ) where d is the depth of X

3/22

§3 Binary Search Trees

Position Iter_Find( ElementType X, SearchTree T )
{
/* iterative version of Find */
while ( T ) {
if ( X == T->Element )
return T ; /* found */
if ( X < T->Element )
T = T->Left ; /*move down along left path */
else
T = T-> Right ; /* move down along right path */
} /* end while-loop */
return NULL ; /* not found */
}

4/22



FindMin

§3 Binary Search Trees

Position FindMin( SearchTree T )
T( N ) = O ( d )
{
if ( T == NULL )
return NULL; /* not found in an empty tree */
else
if ( T->Left == NULL ) return T; /* found left most */
else return FindMin( T->Left ); /* keep moving to left */
}

 FindMax
Position FindMax( SearchTree T )
T( N ) = O ( d )
{
if ( T != NULL )
while ( T->Right != NULL )
T = T->Right; /* keep moving to find right most */
return T; /* return NULL or the right most */
}

5/22

§3 Binary Search Trees

 Insert
Sketch of the idea:
Insert 80

30
5
2

40
25 35

Insert 35

Insert 25

6/22

 check if 80 is already in the tree
 80 > 40, so it must be the right child
80

of 40

Thisifis35
theis last
nodein the tree
 check
already
we encounter
 35search
< 40, so it must be the left child of 40
when
for the key number.
It will be the parent
 check if 25 is already in the tree
of the new node.
 25 > 5, so it must be the right child of 5

§3 Binary Search Trees
SearchTree Insert( ElementType X, SearchTree T )
{
if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct TreeNode ) );
if ( T == NULL )
FatalError( "Out of space!!!" );
else {
T->Element = X;
How would you
T->Left = T->Right = NULL; }
Handle
T(
N ) = duplicated
O(d)
} /* End creating a one-node tree */
Keys?
else /* If there is a tree */
if ( X < T->Element )
T->Left = Insert( X, T->Left );
else
if ( X > T->Element )
T->Right = Insert( X, T->Right );
/* Else X is in the tree already; we'll do nothing */
return T; /* Do not forget this line!! */
}

7/22

§3 Binary Search Trees

 Delete

 Delete a leaf nodeNote:
: Reset
its kinds
parentoflink
to NULL.
These
nodes
have: degree
atthe
most
1. by its single child.
 Delete a degree 1 node
Replace
node
 Delete a degree 2 node :

 Replace the node by the largest one in its left subtree or
the smallest one in its right subtree.
 Delete the replacing node from the subtree.

〖Example〗 Delete 60

40
20

Solution 1: reset left subtree.

10

60
55
30

50 70

Solution 2: reset right subtree.

45

55
52
52

8/22

§3 Binary Search Trees
SearchTree Delete( ElementType X, SearchTree T )
{ Position TmpCell;
if ( T == NULL ) Error( "Element not found" );
else if ( X < T->Element ) /* Go left */
T->Left = Delete( X, T->Left );
else if ( X > T->Element ) /* Go right */
T->Right = Delete( X, T->Right );
else /* Found element to be deleted */
if ( T->Left && T->Right ) { /* Two children */
/* Replace with smallest in right subtree */
TmpCell = FindMin( T->Right );
T->Element = TmpCell->Element;
T->Right = Delete( T->Element, T->Right ); } /* End if */
else { /* One or zero child */
TmpCell = T;
if ( T->Left == NULL ) /* Also handles 0 child */
T = T->Right;
else if ( T->Right == NULL ) T = T->Left;
free( TmpCell ); } /* End else 1 or 0 child */
return T;
T( N ) = O ( h ) where h is the height of the tree
}
9/22

§3 Binary Search Trees

Note:
If there are not many deletions, then lazy deletion
may be employed: add a flag field to each node, to mark
if a node is active or is deleted. Therefore we can delete
a node without actually freeing the space of that node.
If a deleted key is reinserted, we won’t have to call
malloc again.

While the number of deleted nodes
is the same as the number of active nodes
in the tree, will it seriously affect
the efficiency of the operations?

10/22

§3 Binary Search Trees

4. Average-Case Analysis
Question: Place n elements in a binary search tree. How
high can this tree be?

Answer: The height depends on the order of insertion.
〖Example〗 Given elements 1, 2, 3, 4, 5, 6, 7. Insert
them into a binary search tree in the orders:
4, 2, 1, 3, 6, 5, 7
and
1, 2, 3, 4, 5, 6, 7
4
2
1

6
3

5

h=2

11/22

h=6
7

§3 Binary Search Trees

【Definition】The internal path length for a tree of N nodes
N

is defined to be:

D( N )   d ( i ) , D(1)  0
i 1

where d( i ) is the
depth of work:
node i.
Home

【Theorem】 Assume that all binary search trees are equally
p.139 4.42
likely. Then the average D(N) (taken over all possible
Isomorphic
Trees
insertion sequences)
is O(N log
N). Thus the expected
depth of any node is O(log N).

p.140 4.45
D( N ) = D( i ) + D( N  i  1 ) + N  1
Threaded Trees

Proof:
Since all subtree sizes are
equally likely, the average
i nodes
value of both D( i ) and
N 1
D( N  i  1 ) is [ j  0 D( j )] N .

D( N ) 
12/22

2
N

[ j 0 D( j )]  N  1 =
N 1

root
+1
N  i  1 nodes

p.212-213

= O(N log N)

§4 AVL Trees
Target : Speed up searching (with insertion and
deletion)

root

Tool : Binary search trees
small

large

Problem : Although Tp = O( height ), but the
height can be as bad as O( N ).

13/22

§4 AVL Trees

〖Example〗 3 binary search trees obtained for the months
of the year
Jan

Average search time = ?3.5

Feb

Mar

Apr

June
Aug

May

July

Sept

Dec

Oct

Entered from Jan to Dec

AST = 6.5

Nov

July
Feb

Aug
Apr

May

Jan
Dec

Mar
June

A balanced tree
14/22

What if the months
are entered in
alphabetical order?

Average search time = ?3.1
Oct

Nov

Sept

§4 AVL Trees

Adelson-Velskii-Landis (AVL) Trees (1962)
【Definition】An empty binary tree is height balanced. If T is a
nonempty binary tree with TL and TR as its left and right
subtrees, then T is height balanced iff
(1) TL and TR are height balanced, and
The height of an empty tree
(2) | hL  hR |  1 where hL and hisR defined
are thetoheights
be –1. of TL and TR ,
respectively.

【Definition】The balance factor BF( node ) = hL  hR . In an
AVL tree, BF( node ) = 1, 0, or 1.
4

3
2
1
15/22

5

5

2
6

1
7

8
4 7

3

7

2
1

8
4

3

5

§4 AVL Trees

〖Example〗 Input the months

Mar

May

1
2
0

Mar

Nov
1
2
01
0

1
0

May

Single rotation

May
0

00

00

Mar

Nov

Nov

 The trouble maker Nov is in the right subtree’s right
subtree of the trouble finder Mar. Hence it is called an
RR rotation.
A is not necessarily
In general:
the root of the tree
1

A

RR
0

16/22

1

BR

B
BL

0

RR

BR

B

A

Rotation

AL

AL
BL

A

Insertion

B

0

2

BR
AL

BL

Aug

§4 AVL Trees

Apr
2
1
01
12

1
2
01
1

LL

May
210

00

Mar

Nov

1
010

Rotation

May
00

Aug

Nov

10

0

0

Aug

Apr

Mar

0

Apr
In general:
1
0

2

LL

A

1

Insertion

B

A

17/22

BR

LL

B
AR
BL

B

Rotation

AR
BL

0

BR

0

A
BL
BR

AR

§4 AVL Trees

Jan

21
2
1
01

Double Rotation

1
2
01
0

May

1
010

00

Aug

1
010

Nov

0

10

Apr

Mar

Aug

LR

0

Jan

Mar

1
0

May

0

0

Apr

Jan

0

Nov

Rotation

In general:
1
0

B

A

CL

Insertion

1

B

0

C
BL

2

LR

A

BL

CL

18/22

0 or 1

C

1 or 0

B

AR
CR

OR

0

Rotation

1

C

AR
CR

LR

BL

A
CL

CR
OR

AR

Dec

July

§4 AVL Trees

Feb

1
2
01
21

Mar

1
2
10

Aug

1
0

May

0

01

Apr

Jan

1
0

Nov

Dec

10

01
10

Aug

Jan

1
0

May
0

Nov

0

0

Apr

Feb

July

2

RL

July
0

Mar

1
02
1
0

Rotation
0

0

Dec

1
2
01
1

RL

0

Feb
In general:
1

A
0

RL
0

Insertion

B

1

C

AL
CL

A

CR

CL

19/22

B

0 or 1

C

1 or 0

A
CR

OR

0

Rotation

C

AL
BR

1

BR
AL

B
CL

CR
OR

BR

June

Oct

§4 AVL Trees

Sept
1
0

1
0 2
1
01
21

Jan
Mar
Jan
1
1
12
1
0 1
00
02
1
0
1
1
12
1
0
0 1
Dec
Mar
May
Dec Dec
Mar

1 10

1 Aug
Aug

Aug

0 0

0 Apr
Apr

Apr

0

0

Feb
Feb0
Feb

01
10 1
1
Jan

July
July

1
00

0 July
June

June

2
10

1
0
May
Nov
Nov

1
0 1
0
Nov 0
Oct
May
0
0

June

Note: Several bf’s
might be changed even if
we don’t need to reconstruct
the tree.

Oct 0
Sept

Another option is to keep a height field for each node.

20/22

§4 AVL Trees
AvlTree Insert( ElementType X, AvlTree T )
{ if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct AvlNode ) );
if ( T == NULL ) FatalError( "Out of space!!!" );
else { T->Element = X; T->Height = 0; T->Left = T->Right = NULL; }
} /* End creating a one-node tree */
else if ( X < T->Element ) { /* handle left insertion */
T->Left = Insert( X, T->Left );
if ( Height( T->Left ) - Height( T->Right ) == 2 ) /* not balanced */
if ( X < T->Left->Element ) /* LL Rotation */
T = SingleRotateWithLeft( T );
else /* LR Rotation */
T = DoubleRotateWithLeft( T ); } /* End left */
else if( X > T->Element ) { /* handle right insertion */
T->Right = Insert( X, T->Right );
if ( Height( T->Right ) - Height( T->Left ) == 2 ) /* not balanced */
if ( X > T->Right->Element ) /* RR Rotation */
T = SingleRotateWithRight( T );
else /* RL Rotation */
T = DoubleRotateWithRight( T ); } /* End right */
/* Else X is in the tree already; we'll do nothing */
T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
return T;
}

Home work:

p.136 4.16
Create an AVL Tree
p.136 4.22
Double Rotation

21/22

§4 AVL Trees

Let nh be the minimum number of nodes in a height balanced tree of
height h. Then the tree must look like

A
h2

A
h1

last question:
OROne
h1
h2  nh = nh1 + nh2 + 1

Obviously we have Tp = O( h )
where h is the height of the tree.
But h = ?

Fibonacci numbers:
F0 = 0, F1 = 1, Fi = Fi1 + Fi2 for i > 1
 nh = Fh+2  1, for h  0
i


1  1 5 
Fibonacci number theory gives that Fi 


1  1  5 
 nh 
5  2 
22/22

5

h 2

1

 h  O(lnn)

2




Slide 20

§3 The Search Tree ADT -- Binary Search Trees
1. Definition
【Definition】A binary search tree is a binary tree. It may be
(1)
(2)
(3)
(4)

empty. If it is not empty, it satisfies the following properties:
Every node has a key which is an integer, and the keys are
distinct.
The keys in a nonempty left subtree must be smaller than
the key in the root of the subtree.
The keys in a nonempty right subtree must be larger than
the key in the root of the subtree.
The left and right subtrees are also binary search trees.

30

5
2

1/22

60

40

20
70

65

15
80

12

10

25
22

§3 Binary Search Trees

2. ADT
Objects: A finite ordered list with zero or more elements.
Operations:

 SearchTree MakeEmpty( SearchTree T );
 Position Find( ElementType X, SearchTree T );
 Position FindMin( SearchTree T );
 Position FindMax( SearchTree T );
 SearchTree Insert( ElementType X, SearchTree T );
 SearchTree Delete( ElementType X, SearchTree T );
 ElementType Retrieve( Position P );

2/22

§3 Binary Search Trees

3. Implementations

 Find

Must this test
be performed first?

Position Find( ElementType X, SearchTree T )
{
if ( T == NULL )
These are
return NULL; /* not found in an empty tree */
tail recursions.
if ( X < T->Element ) /* if smaller than root */
return Find( X, T->Left ); /* search left subtree */
else
if ( X > T->Element ) /* if larger than root */
return Find( X, T->Right ); /* search right subtree */
else /* if X == root */
return T; /* found */
}
T( N ) = S ( N ) = O( d ) where d is the depth of X

3/22

§3 Binary Search Trees

Position Iter_Find( ElementType X, SearchTree T )
{
/* iterative version of Find */
while ( T ) {
if ( X == T->Element )
return T ; /* found */
if ( X < T->Element )
T = T->Left ; /*move down along left path */
else
T = T-> Right ; /* move down along right path */
} /* end while-loop */
return NULL ; /* not found */
}

4/22



FindMin

§3 Binary Search Trees

Position FindMin( SearchTree T )
T( N ) = O ( d )
{
if ( T == NULL )
return NULL; /* not found in an empty tree */
else
if ( T->Left == NULL ) return T; /* found left most */
else return FindMin( T->Left ); /* keep moving to left */
}

 FindMax
Position FindMax( SearchTree T )
T( N ) = O ( d )
{
if ( T != NULL )
while ( T->Right != NULL )
T = T->Right; /* keep moving to find right most */
return T; /* return NULL or the right most */
}

5/22

§3 Binary Search Trees

 Insert
Sketch of the idea:
Insert 80

30
5
2

40
25 35

Insert 35

Insert 25

6/22

 check if 80 is already in the tree
 80 > 40, so it must be the right child
80

of 40

Thisifis35
theis last
nodein the tree
 check
already
we encounter
 35search
< 40, so it must be the left child of 40
when
for the key number.
It will be the parent
 check if 25 is already in the tree
of the new node.
 25 > 5, so it must be the right child of 5

§3 Binary Search Trees
SearchTree Insert( ElementType X, SearchTree T )
{
if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct TreeNode ) );
if ( T == NULL )
FatalError( "Out of space!!!" );
else {
T->Element = X;
How would you
T->Left = T->Right = NULL; }
Handle
T(
N ) = duplicated
O(d)
} /* End creating a one-node tree */
Keys?
else /* If there is a tree */
if ( X < T->Element )
T->Left = Insert( X, T->Left );
else
if ( X > T->Element )
T->Right = Insert( X, T->Right );
/* Else X is in the tree already; we'll do nothing */
return T; /* Do not forget this line!! */
}

7/22

§3 Binary Search Trees

 Delete

 Delete a leaf nodeNote:
: Reset
its kinds
parentoflink
to NULL.
These
nodes
have: degree
atthe
most
1. by its single child.
 Delete a degree 1 node
Replace
node
 Delete a degree 2 node :

 Replace the node by the largest one in its left subtree or
the smallest one in its right subtree.
 Delete the replacing node from the subtree.

〖Example〗 Delete 60

40
20

Solution 1: reset left subtree.

10

60
55
30

50 70

Solution 2: reset right subtree.

45

55
52
52

8/22

§3 Binary Search Trees
SearchTree Delete( ElementType X, SearchTree T )
{ Position TmpCell;
if ( T == NULL ) Error( "Element not found" );
else if ( X < T->Element ) /* Go left */
T->Left = Delete( X, T->Left );
else if ( X > T->Element ) /* Go right */
T->Right = Delete( X, T->Right );
else /* Found element to be deleted */
if ( T->Left && T->Right ) { /* Two children */
/* Replace with smallest in right subtree */
TmpCell = FindMin( T->Right );
T->Element = TmpCell->Element;
T->Right = Delete( T->Element, T->Right ); } /* End if */
else { /* One or zero child */
TmpCell = T;
if ( T->Left == NULL ) /* Also handles 0 child */
T = T->Right;
else if ( T->Right == NULL ) T = T->Left;
free( TmpCell ); } /* End else 1 or 0 child */
return T;
T( N ) = O ( h ) where h is the height of the tree
}
9/22

§3 Binary Search Trees

Note:
If there are not many deletions, then lazy deletion
may be employed: add a flag field to each node, to mark
if a node is active or is deleted. Therefore we can delete
a node without actually freeing the space of that node.
If a deleted key is reinserted, we won’t have to call
malloc again.

While the number of deleted nodes
is the same as the number of active nodes
in the tree, will it seriously affect
the efficiency of the operations?

10/22

§3 Binary Search Trees

4. Average-Case Analysis
Question: Place n elements in a binary search tree. How
high can this tree be?

Answer: The height depends on the order of insertion.
〖Example〗 Given elements 1, 2, 3, 4, 5, 6, 7. Insert
them into a binary search tree in the orders:
4, 2, 1, 3, 6, 5, 7
and
1, 2, 3, 4, 5, 6, 7
4
2
1

6
3

5

h=2

11/22

h=6
7

§3 Binary Search Trees

【Definition】The internal path length for a tree of N nodes
N

is defined to be:

D( N )   d ( i ) , D(1)  0
i 1

where d( i ) is the
depth of work:
node i.
Home

【Theorem】 Assume that all binary search trees are equally
p.139 4.42
likely. Then the average D(N) (taken over all possible
Isomorphic
Trees
insertion sequences)
is O(N log
N). Thus the expected
depth of any node is O(log N).

p.140 4.45
D( N ) = D( i ) + D( N  i  1 ) + N  1
Threaded Trees

Proof:
Since all subtree sizes are
equally likely, the average
i nodes
value of both D( i ) and
N 1
D( N  i  1 ) is [ j  0 D( j )] N .

D( N ) 
12/22

2
N

[ j 0 D( j )]  N  1 =
N 1

root
+1
N  i  1 nodes

p.212-213

= O(N log N)

§4 AVL Trees
Target : Speed up searching (with insertion and
deletion)

root

Tool : Binary search trees
small

large

Problem : Although Tp = O( height ), but the
height can be as bad as O( N ).

13/22

§4 AVL Trees

〖Example〗 3 binary search trees obtained for the months
of the year
Jan

Average search time = ?3.5

Feb

Mar

Apr

June
Aug

May

July

Sept

Dec

Oct

Entered from Jan to Dec

AST = 6.5

Nov

July
Feb

Aug
Apr

May

Jan
Dec

Mar
June

A balanced tree
14/22

What if the months
are entered in
alphabetical order?

Average search time = ?3.1
Oct

Nov

Sept

§4 AVL Trees

Adelson-Velskii-Landis (AVL) Trees (1962)
【Definition】An empty binary tree is height balanced. If T is a
nonempty binary tree with TL and TR as its left and right
subtrees, then T is height balanced iff
(1) TL and TR are height balanced, and
The height of an empty tree
(2) | hL  hR |  1 where hL and hisR defined
are thetoheights
be –1. of TL and TR ,
respectively.

【Definition】The balance factor BF( node ) = hL  hR . In an
AVL tree, BF( node ) = 1, 0, or 1.
4

3
2
1
15/22

5

5

2
6

1
7

8
4 7

3

7

2
1

8
4

3

5

§4 AVL Trees

〖Example〗 Input the months

Mar

May

1
2
0

Mar

Nov
1
2
01
0

1
0

May

Single rotation

May
0

00

00

Mar

Nov

Nov

 The trouble maker Nov is in the right subtree’s right
subtree of the trouble finder Mar. Hence it is called an
RR rotation.
A is not necessarily
In general:
the root of the tree
1

A

RR
0

16/22

1

BR

B
BL

0

RR

BR

B

A

Rotation

AL

AL
BL

A

Insertion

B

0

2

BR
AL

BL

Aug

§4 AVL Trees

Apr
2
1
01
12

1
2
01
1

LL

May
210

00

Mar

Nov

1
010

Rotation

May
00

Aug

Nov

10

0

0

Aug

Apr

Mar

0

Apr
In general:
1
0

2

LL

A

1

Insertion

B

A

17/22

BR

LL

B
AR
BL

B

Rotation

AR
BL

0

BR

0

A
BL
BR

AR

§4 AVL Trees

Jan

21
2
1
01

Double Rotation

1
2
01
0

May

1
010

00

Aug

1
010

Nov

0

10

Apr

Mar

Aug

LR

0

Jan

Mar

1
0

May

0

0

Apr

Jan

0

Nov

Rotation

In general:
1
0

B

A

CL

Insertion

1

B

0

C
BL

2

LR

A

BL

CL

18/22

0 or 1

C

1 or 0

B

AR
CR

OR

0

Rotation

1

C

AR
CR

LR

BL

A
CL

CR
OR

AR

Dec

July

§4 AVL Trees

Feb

1
2
01
21

Mar

1
2
10

Aug

1
0

May

0

01

Apr

Jan

1
0

Nov

Dec

10

01
10

Aug

Jan

1
0

May
0

Nov

0

0

Apr

Feb

July

2

RL

July
0

Mar

1
02
1
0

Rotation
0

0

Dec

1
2
01
1

RL

0

Feb
In general:
1

A
0

RL
0

Insertion

B

1

C

AL
CL

A

CR

CL

19/22

B

0 or 1

C

1 or 0

A
CR

OR

0

Rotation

C

AL
BR

1

BR
AL

B
CL

CR
OR

BR

June

Oct

§4 AVL Trees

Sept
1
0

1
0 2
1
01
21

Jan
Mar
Jan
1
1
12
1
0 1
00
02
1
0
1
1
12
1
0
0 1
Dec
Mar
May
Dec Dec
Mar

1 10

1 Aug
Aug

Aug

0 0

0 Apr
Apr

Apr

0

0

Feb
Feb0
Feb

01
10 1
1
Jan

July
July

1
00

0 July
June

June

2
10

1
0
May
Nov
Nov

1
0 1
0
Nov 0
Oct
May
0
0

June

Note: Several bf’s
might be changed even if
we don’t need to reconstruct
the tree.

Oct 0
Sept

Another option is to keep a height field for each node.

20/22

§4 AVL Trees
AvlTree Insert( ElementType X, AvlTree T )
{ if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct AvlNode ) );
if ( T == NULL ) FatalError( "Out of space!!!" );
else { T->Element = X; T->Height = 0; T->Left = T->Right = NULL; }
} /* End creating a one-node tree */
else if ( X < T->Element ) { /* handle left insertion */
T->Left = Insert( X, T->Left );
if ( Height( T->Left ) - Height( T->Right ) == 2 ) /* not balanced */
if ( X < T->Left->Element ) /* LL Rotation */
T = SingleRotateWithLeft( T );
else /* LR Rotation */
T = DoubleRotateWithLeft( T ); } /* End left */
else if( X > T->Element ) { /* handle right insertion */
T->Right = Insert( X, T->Right );
if ( Height( T->Right ) - Height( T->Left ) == 2 ) /* not balanced */
if ( X > T->Right->Element ) /* RR Rotation */
T = SingleRotateWithRight( T );
else /* RL Rotation */
T = DoubleRotateWithRight( T ); } /* End right */
/* Else X is in the tree already; we'll do nothing */
T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
return T;
}

Home work:

p.136 4.16
Create an AVL Tree
p.136 4.22
Double Rotation

21/22

§4 AVL Trees

Let nh be the minimum number of nodes in a height balanced tree of
height h. Then the tree must look like

A
h2

A
h1

last question:
OROne
h1
h2  nh = nh1 + nh2 + 1

Obviously we have Tp = O( h )
where h is the height of the tree.
But h = ?

Fibonacci numbers:
F0 = 0, F1 = 1, Fi = Fi1 + Fi2 for i > 1
 nh = Fh+2  1, for h  0
i


1  1 5 
Fibonacci number theory gives that Fi 


1  1  5 
 nh 
5  2 
22/22

5

h 2

1

 h  O(lnn)

2




Slide 21

§3 The Search Tree ADT -- Binary Search Trees
1. Definition
【Definition】A binary search tree is a binary tree. It may be
(1)
(2)
(3)
(4)

empty. If it is not empty, it satisfies the following properties:
Every node has a key which is an integer, and the keys are
distinct.
The keys in a nonempty left subtree must be smaller than
the key in the root of the subtree.
The keys in a nonempty right subtree must be larger than
the key in the root of the subtree.
The left and right subtrees are also binary search trees.

30

5
2

1/22

60

40

20
70

65

15
80

12

10

25
22

§3 Binary Search Trees

2. ADT
Objects: A finite ordered list with zero or more elements.
Operations:

 SearchTree MakeEmpty( SearchTree T );
 Position Find( ElementType X, SearchTree T );
 Position FindMin( SearchTree T );
 Position FindMax( SearchTree T );
 SearchTree Insert( ElementType X, SearchTree T );
 SearchTree Delete( ElementType X, SearchTree T );
 ElementType Retrieve( Position P );

2/22

§3 Binary Search Trees

3. Implementations

 Find

Must this test
be performed first?

Position Find( ElementType X, SearchTree T )
{
if ( T == NULL )
These are
return NULL; /* not found in an empty tree */
tail recursions.
if ( X < T->Element ) /* if smaller than root */
return Find( X, T->Left ); /* search left subtree */
else
if ( X > T->Element ) /* if larger than root */
return Find( X, T->Right ); /* search right subtree */
else /* if X == root */
return T; /* found */
}
T( N ) = S ( N ) = O( d ) where d is the depth of X

3/22

§3 Binary Search Trees

Position Iter_Find( ElementType X, SearchTree T )
{
/* iterative version of Find */
while ( T ) {
if ( X == T->Element )
return T ; /* found */
if ( X < T->Element )
T = T->Left ; /*move down along left path */
else
T = T-> Right ; /* move down along right path */
} /* end while-loop */
return NULL ; /* not found */
}

4/22



FindMin

§3 Binary Search Trees

Position FindMin( SearchTree T )
T( N ) = O ( d )
{
if ( T == NULL )
return NULL; /* not found in an empty tree */
else
if ( T->Left == NULL ) return T; /* found left most */
else return FindMin( T->Left ); /* keep moving to left */
}

 FindMax
Position FindMax( SearchTree T )
T( N ) = O ( d )
{
if ( T != NULL )
while ( T->Right != NULL )
T = T->Right; /* keep moving to find right most */
return T; /* return NULL or the right most */
}

5/22

§3 Binary Search Trees

 Insert
Sketch of the idea:
Insert 80

30
5
2

40
25 35

Insert 35

Insert 25

6/22

 check if 80 is already in the tree
 80 > 40, so it must be the right child
80

of 40

Thisifis35
theis last
nodein the tree
 check
already
we encounter
 35search
< 40, so it must be the left child of 40
when
for the key number.
It will be the parent
 check if 25 is already in the tree
of the new node.
 25 > 5, so it must be the right child of 5

§3 Binary Search Trees
SearchTree Insert( ElementType X, SearchTree T )
{
if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct TreeNode ) );
if ( T == NULL )
FatalError( "Out of space!!!" );
else {
T->Element = X;
How would you
T->Left = T->Right = NULL; }
Handle
T(
N ) = duplicated
O(d)
} /* End creating a one-node tree */
Keys?
else /* If there is a tree */
if ( X < T->Element )
T->Left = Insert( X, T->Left );
else
if ( X > T->Element )
T->Right = Insert( X, T->Right );
/* Else X is in the tree already; we'll do nothing */
return T; /* Do not forget this line!! */
}

7/22

§3 Binary Search Trees

 Delete

 Delete a leaf nodeNote:
: Reset
its kinds
parentoflink
to NULL.
These
nodes
have: degree
atthe
most
1. by its single child.
 Delete a degree 1 node
Replace
node
 Delete a degree 2 node :

 Replace the node by the largest one in its left subtree or
the smallest one in its right subtree.
 Delete the replacing node from the subtree.

〖Example〗 Delete 60

40
20

Solution 1: reset left subtree.

10

60
55
30

50 70

Solution 2: reset right subtree.

45

55
52
52

8/22

§3 Binary Search Trees
SearchTree Delete( ElementType X, SearchTree T )
{ Position TmpCell;
if ( T == NULL ) Error( "Element not found" );
else if ( X < T->Element ) /* Go left */
T->Left = Delete( X, T->Left );
else if ( X > T->Element ) /* Go right */
T->Right = Delete( X, T->Right );
else /* Found element to be deleted */
if ( T->Left && T->Right ) { /* Two children */
/* Replace with smallest in right subtree */
TmpCell = FindMin( T->Right );
T->Element = TmpCell->Element;
T->Right = Delete( T->Element, T->Right ); } /* End if */
else { /* One or zero child */
TmpCell = T;
if ( T->Left == NULL ) /* Also handles 0 child */
T = T->Right;
else if ( T->Right == NULL ) T = T->Left;
free( TmpCell ); } /* End else 1 or 0 child */
return T;
T( N ) = O ( h ) where h is the height of the tree
}
9/22

§3 Binary Search Trees

Note:
If there are not many deletions, then lazy deletion
may be employed: add a flag field to each node, to mark
if a node is active or is deleted. Therefore we can delete
a node without actually freeing the space of that node.
If a deleted key is reinserted, we won’t have to call
malloc again.

While the number of deleted nodes
is the same as the number of active nodes
in the tree, will it seriously affect
the efficiency of the operations?

10/22

§3 Binary Search Trees

4. Average-Case Analysis
Question: Place n elements in a binary search tree. How
high can this tree be?

Answer: The height depends on the order of insertion.
〖Example〗 Given elements 1, 2, 3, 4, 5, 6, 7. Insert
them into a binary search tree in the orders:
4, 2, 1, 3, 6, 5, 7
and
1, 2, 3, 4, 5, 6, 7
4
2
1

6
3

5

h=2

11/22

h=6
7

§3 Binary Search Trees

【Definition】The internal path length for a tree of N nodes
N

is defined to be:

D( N )   d ( i ) , D(1)  0
i 1

where d( i ) is the
depth of work:
node i.
Home

【Theorem】 Assume that all binary search trees are equally
p.139 4.42
likely. Then the average D(N) (taken over all possible
Isomorphic
Trees
insertion sequences)
is O(N log
N). Thus the expected
depth of any node is O(log N).

p.140 4.45
D( N ) = D( i ) + D( N  i  1 ) + N  1
Threaded Trees

Proof:
Since all subtree sizes are
equally likely, the average
i nodes
value of both D( i ) and
N 1
D( N  i  1 ) is [ j  0 D( j )] N .

D( N ) 
12/22

2
N

[ j 0 D( j )]  N  1 =
N 1

root
+1
N  i  1 nodes

p.212-213

= O(N log N)

§4 AVL Trees
Target : Speed up searching (with insertion and
deletion)

root

Tool : Binary search trees
small

large

Problem : Although Tp = O( height ), but the
height can be as bad as O( N ).

13/22

§4 AVL Trees

〖Example〗 3 binary search trees obtained for the months
of the year
Jan

Average search time = ?3.5

Feb

Mar

Apr

June
Aug

May

July

Sept

Dec

Oct

Entered from Jan to Dec

AST = 6.5

Nov

July
Feb

Aug
Apr

May

Jan
Dec

Mar
June

A balanced tree
14/22

What if the months
are entered in
alphabetical order?

Average search time = ?3.1
Oct

Nov

Sept

§4 AVL Trees

Adelson-Velskii-Landis (AVL) Trees (1962)
【Definition】An empty binary tree is height balanced. If T is a
nonempty binary tree with TL and TR as its left and right
subtrees, then T is height balanced iff
(1) TL and TR are height balanced, and
The height of an empty tree
(2) | hL  hR |  1 where hL and hisR defined
are thetoheights
be –1. of TL and TR ,
respectively.

【Definition】The balance factor BF( node ) = hL  hR . In an
AVL tree, BF( node ) = 1, 0, or 1.
4

3
2
1
15/22

5

5

2
6

1
7

8
4 7

3

7

2
1

8
4

3

5

§4 AVL Trees

〖Example〗 Input the months

Mar

May

1
2
0

Mar

Nov
1
2
01
0

1
0

May

Single rotation

May
0

00

00

Mar

Nov

Nov

 The trouble maker Nov is in the right subtree’s right
subtree of the trouble finder Mar. Hence it is called an
RR rotation.
A is not necessarily
In general:
the root of the tree
1

A

RR
0

16/22

1

BR

B
BL

0

RR

BR

B

A

Rotation

AL

AL
BL

A

Insertion

B

0

2

BR
AL

BL

Aug

§4 AVL Trees

Apr
2
1
01
12

1
2
01
1

LL

May
210

00

Mar

Nov

1
010

Rotation

May
00

Aug

Nov

10

0

0

Aug

Apr

Mar

0

Apr
In general:
1
0

2

LL

A

1

Insertion

B

A

17/22

BR

LL

B
AR
BL

B

Rotation

AR
BL

0

BR

0

A
BL
BR

AR

§4 AVL Trees

Jan

21
2
1
01

Double Rotation

1
2
01
0

May

1
010

00

Aug

1
010

Nov

0

10

Apr

Mar

Aug

LR

0

Jan

Mar

1
0

May

0

0

Apr

Jan

0

Nov

Rotation

In general:
1
0

B

A

CL

Insertion

1

B

0

C
BL

2

LR

A

BL

CL

18/22

0 or 1

C

1 or 0

B

AR
CR

OR

0

Rotation

1

C

AR
CR

LR

BL

A
CL

CR
OR

AR

Dec

July

§4 AVL Trees

Feb

1
2
01
21

Mar

1
2
10

Aug

1
0

May

0

01

Apr

Jan

1
0

Nov

Dec

10

01
10

Aug

Jan

1
0

May
0

Nov

0

0

Apr

Feb

July

2

RL

July
0

Mar

1
02
1
0

Rotation
0

0

Dec

1
2
01
1

RL

0

Feb
In general:
1

A
0

RL
0

Insertion

B

1

C

AL
CL

A

CR

CL

19/22

B

0 or 1

C

1 or 0

A
CR

OR

0

Rotation

C

AL
BR

1

BR
AL

B
CL

CR
OR

BR

June

Oct

§4 AVL Trees

Sept
1
0

1
0 2
1
01
21

Jan
Mar
Jan
1
1
12
1
0 1
00
02
1
0
1
1
12
1
0
0 1
Dec
Mar
May
Dec Dec
Mar

1 10

1 Aug
Aug

Aug

0 0

0 Apr
Apr

Apr

0

0

Feb
Feb0
Feb

01
10 1
1
Jan

July
July

1
00

0 July
June

June

2
10

1
0
May
Nov
Nov

1
0 1
0
Nov 0
Oct
May
0
0

June

Note: Several bf’s
might be changed even if
we don’t need to reconstruct
the tree.

Oct 0
Sept

Another option is to keep a height field for each node.

20/22

§4 AVL Trees
AvlTree Insert( ElementType X, AvlTree T )
{ if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct AvlNode ) );
if ( T == NULL ) FatalError( "Out of space!!!" );
else { T->Element = X; T->Height = 0; T->Left = T->Right = NULL; }
} /* End creating a one-node tree */
else if ( X < T->Element ) { /* handle left insertion */
T->Left = Insert( X, T->Left );
if ( Height( T->Left ) - Height( T->Right ) == 2 ) /* not balanced */
if ( X < T->Left->Element ) /* LL Rotation */
T = SingleRotateWithLeft( T );
else /* LR Rotation */
T = DoubleRotateWithLeft( T ); } /* End left */
else if( X > T->Element ) { /* handle right insertion */
T->Right = Insert( X, T->Right );
if ( Height( T->Right ) - Height( T->Left ) == 2 ) /* not balanced */
if ( X > T->Right->Element ) /* RR Rotation */
T = SingleRotateWithRight( T );
else /* RL Rotation */
T = DoubleRotateWithRight( T ); } /* End right */
/* Else X is in the tree already; we'll do nothing */
T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
return T;
}

Home work:

p.136 4.16
Create an AVL Tree
p.136 4.22
Double Rotation

21/22

§4 AVL Trees

Let nh be the minimum number of nodes in a height balanced tree of
height h. Then the tree must look like

A
h2

A
h1

last question:
OROne
h1
h2  nh = nh1 + nh2 + 1

Obviously we have Tp = O( h )
where h is the height of the tree.
But h = ?

Fibonacci numbers:
F0 = 0, F1 = 1, Fi = Fi1 + Fi2 for i > 1
 nh = Fh+2  1, for h  0
i


1  1 5 
Fibonacci number theory gives that Fi 


1  1  5 
 nh 
5  2 
22/22

5

h 2

1

 h  O(lnn)

2




Slide 22

§3 The Search Tree ADT -- Binary Search Trees
1. Definition
【Definition】A binary search tree is a binary tree. It may be
(1)
(2)
(3)
(4)

empty. If it is not empty, it satisfies the following properties:
Every node has a key which is an integer, and the keys are
distinct.
The keys in a nonempty left subtree must be smaller than
the key in the root of the subtree.
The keys in a nonempty right subtree must be larger than
the key in the root of the subtree.
The left and right subtrees are also binary search trees.

30

5
2

1/22

60

40

20
70

65

15
80

12

10

25
22

§3 Binary Search Trees

2. ADT
Objects: A finite ordered list with zero or more elements.
Operations:

 SearchTree MakeEmpty( SearchTree T );
 Position Find( ElementType X, SearchTree T );
 Position FindMin( SearchTree T );
 Position FindMax( SearchTree T );
 SearchTree Insert( ElementType X, SearchTree T );
 SearchTree Delete( ElementType X, SearchTree T );
 ElementType Retrieve( Position P );

2/22

§3 Binary Search Trees

3. Implementations

 Find

Must this test
be performed first?

Position Find( ElementType X, SearchTree T )
{
if ( T == NULL )
These are
return NULL; /* not found in an empty tree */
tail recursions.
if ( X < T->Element ) /* if smaller than root */
return Find( X, T->Left ); /* search left subtree */
else
if ( X > T->Element ) /* if larger than root */
return Find( X, T->Right ); /* search right subtree */
else /* if X == root */
return T; /* found */
}
T( N ) = S ( N ) = O( d ) where d is the depth of X

3/22

§3 Binary Search Trees

Position Iter_Find( ElementType X, SearchTree T )
{
/* iterative version of Find */
while ( T ) {
if ( X == T->Element )
return T ; /* found */
if ( X < T->Element )
T = T->Left ; /*move down along left path */
else
T = T-> Right ; /* move down along right path */
} /* end while-loop */
return NULL ; /* not found */
}

4/22



FindMin

§3 Binary Search Trees

Position FindMin( SearchTree T )
T( N ) = O ( d )
{
if ( T == NULL )
return NULL; /* not found in an empty tree */
else
if ( T->Left == NULL ) return T; /* found left most */
else return FindMin( T->Left ); /* keep moving to left */
}

 FindMax
Position FindMax( SearchTree T )
T( N ) = O ( d )
{
if ( T != NULL )
while ( T->Right != NULL )
T = T->Right; /* keep moving to find right most */
return T; /* return NULL or the right most */
}

5/22

§3 Binary Search Trees

 Insert
Sketch of the idea:
Insert 80

30
5
2

40
25 35

Insert 35

Insert 25

6/22

 check if 80 is already in the tree
 80 > 40, so it must be the right child
80

of 40

Thisifis35
theis last
nodein the tree
 check
already
we encounter
 35search
< 40, so it must be the left child of 40
when
for the key number.
It will be the parent
 check if 25 is already in the tree
of the new node.
 25 > 5, so it must be the right child of 5

§3 Binary Search Trees
SearchTree Insert( ElementType X, SearchTree T )
{
if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct TreeNode ) );
if ( T == NULL )
FatalError( "Out of space!!!" );
else {
T->Element = X;
How would you
T->Left = T->Right = NULL; }
Handle
T(
N ) = duplicated
O(d)
} /* End creating a one-node tree */
Keys?
else /* If there is a tree */
if ( X < T->Element )
T->Left = Insert( X, T->Left );
else
if ( X > T->Element )
T->Right = Insert( X, T->Right );
/* Else X is in the tree already; we'll do nothing */
return T; /* Do not forget this line!! */
}

7/22

§3 Binary Search Trees

 Delete

 Delete a leaf nodeNote:
: Reset
its kinds
parentoflink
to NULL.
These
nodes
have: degree
atthe
most
1. by its single child.
 Delete a degree 1 node
Replace
node
 Delete a degree 2 node :

 Replace the node by the largest one in its left subtree or
the smallest one in its right subtree.
 Delete the replacing node from the subtree.

〖Example〗 Delete 60

40
20

Solution 1: reset left subtree.

10

60
55
30

50 70

Solution 2: reset right subtree.

45

55
52
52

8/22

§3 Binary Search Trees
SearchTree Delete( ElementType X, SearchTree T )
{ Position TmpCell;
if ( T == NULL ) Error( "Element not found" );
else if ( X < T->Element ) /* Go left */
T->Left = Delete( X, T->Left );
else if ( X > T->Element ) /* Go right */
T->Right = Delete( X, T->Right );
else /* Found element to be deleted */
if ( T->Left && T->Right ) { /* Two children */
/* Replace with smallest in right subtree */
TmpCell = FindMin( T->Right );
T->Element = TmpCell->Element;
T->Right = Delete( T->Element, T->Right ); } /* End if */
else { /* One or zero child */
TmpCell = T;
if ( T->Left == NULL ) /* Also handles 0 child */
T = T->Right;
else if ( T->Right == NULL ) T = T->Left;
free( TmpCell ); } /* End else 1 or 0 child */
return T;
T( N ) = O ( h ) where h is the height of the tree
}
9/22

§3 Binary Search Trees

Note:
If there are not many deletions, then lazy deletion
may be employed: add a flag field to each node, to mark
if a node is active or is deleted. Therefore we can delete
a node without actually freeing the space of that node.
If a deleted key is reinserted, we won’t have to call
malloc again.

While the number of deleted nodes
is the same as the number of active nodes
in the tree, will it seriously affect
the efficiency of the operations?

10/22

§3 Binary Search Trees

4. Average-Case Analysis
Question: Place n elements in a binary search tree. How
high can this tree be?

Answer: The height depends on the order of insertion.
〖Example〗 Given elements 1, 2, 3, 4, 5, 6, 7. Insert
them into a binary search tree in the orders:
4, 2, 1, 3, 6, 5, 7
and
1, 2, 3, 4, 5, 6, 7
4
2
1

6
3

5

h=2

11/22

h=6
7

§3 Binary Search Trees

【Definition】The internal path length for a tree of N nodes
N

is defined to be:

D( N )   d ( i ) , D(1)  0
i 1

where d( i ) is the
depth of work:
node i.
Home

【Theorem】 Assume that all binary search trees are equally
p.139 4.42
likely. Then the average D(N) (taken over all possible
Isomorphic
Trees
insertion sequences)
is O(N log
N). Thus the expected
depth of any node is O(log N).

p.140 4.45
D( N ) = D( i ) + D( N  i  1 ) + N  1
Threaded Trees

Proof:
Since all subtree sizes are
equally likely, the average
i nodes
value of both D( i ) and
N 1
D( N  i  1 ) is [ j  0 D( j )] N .

D( N ) 
12/22

2
N

[ j 0 D( j )]  N  1 =
N 1

root
+1
N  i  1 nodes

p.212-213

= O(N log N)

§4 AVL Trees
Target : Speed up searching (with insertion and
deletion)

root

Tool : Binary search trees
small

large

Problem : Although Tp = O( height ), but the
height can be as bad as O( N ).

13/22

§4 AVL Trees

〖Example〗 3 binary search trees obtained for the months
of the year
Jan

Average search time = ?3.5

Feb

Mar

Apr

June
Aug

May

July

Sept

Dec

Oct

Entered from Jan to Dec

AST = 6.5

Nov

July
Feb

Aug
Apr

May

Jan
Dec

Mar
June

A balanced tree
14/22

What if the months
are entered in
alphabetical order?

Average search time = ?3.1
Oct

Nov

Sept

§4 AVL Trees

Adelson-Velskii-Landis (AVL) Trees (1962)
【Definition】An empty binary tree is height balanced. If T is a
nonempty binary tree with TL and TR as its left and right
subtrees, then T is height balanced iff
(1) TL and TR are height balanced, and
The height of an empty tree
(2) | hL  hR |  1 where hL and hisR defined
are thetoheights
be –1. of TL and TR ,
respectively.

【Definition】The balance factor BF( node ) = hL  hR . In an
AVL tree, BF( node ) = 1, 0, or 1.
4

3
2
1
15/22

5

5

2
6

1
7

8
4 7

3

7

2
1

8
4

3

5

§4 AVL Trees

〖Example〗 Input the months

Mar

May

1
2
0

Mar

Nov
1
2
01
0

1
0

May

Single rotation

May
0

00

00

Mar

Nov

Nov

 The trouble maker Nov is in the right subtree’s right
subtree of the trouble finder Mar. Hence it is called an
RR rotation.
A is not necessarily
In general:
the root of the tree
1

A

RR
0

16/22

1

BR

B
BL

0

RR

BR

B

A

Rotation

AL

AL
BL

A

Insertion

B

0

2

BR
AL

BL

Aug

§4 AVL Trees

Apr
2
1
01
12

1
2
01
1

LL

May
210

00

Mar

Nov

1
010

Rotation

May
00

Aug

Nov

10

0

0

Aug

Apr

Mar

0

Apr
In general:
1
0

2

LL

A

1

Insertion

B

A

17/22

BR

LL

B
AR
BL

B

Rotation

AR
BL

0

BR

0

A
BL
BR

AR

§4 AVL Trees

Jan

21
2
1
01

Double Rotation

1
2
01
0

May

1
010

00

Aug

1
010

Nov

0

10

Apr

Mar

Aug

LR

0

Jan

Mar

1
0

May

0

0

Apr

Jan

0

Nov

Rotation

In general:
1
0

B

A

CL

Insertion

1

B

0

C
BL

2

LR

A

BL

CL

18/22

0 or 1

C

1 or 0

B

AR
CR

OR

0

Rotation

1

C

AR
CR

LR

BL

A
CL

CR
OR

AR

Dec

July

§4 AVL Trees

Feb

1
2
01
21

Mar

1
2
10

Aug

1
0

May

0

01

Apr

Jan

1
0

Nov

Dec

10

01
10

Aug

Jan

1
0

May
0

Nov

0

0

Apr

Feb

July

2

RL

July
0

Mar

1
02
1
0

Rotation
0

0

Dec

1
2
01
1

RL

0

Feb
In general:
1

A
0

RL
0

Insertion

B

1

C

AL
CL

A

CR

CL

19/22

B

0 or 1

C

1 or 0

A
CR

OR

0

Rotation

C

AL
BR

1

BR
AL

B
CL

CR
OR

BR

June

Oct

§4 AVL Trees

Sept
1
0

1
0 2
1
01
21

Jan
Mar
Jan
1
1
12
1
0 1
00
02
1
0
1
1
12
1
0
0 1
Dec
Mar
May
Dec Dec
Mar

1 10

1 Aug
Aug

Aug

0 0

0 Apr
Apr

Apr

0

0

Feb
Feb0
Feb

01
10 1
1
Jan

July
July

1
00

0 July
June

June

2
10

1
0
May
Nov
Nov

1
0 1
0
Nov 0
Oct
May
0
0

June

Note: Several bf’s
might be changed even if
we don’t need to reconstruct
the tree.

Oct 0
Sept

Another option is to keep a height field for each node.

20/22

§4 AVL Trees
AvlTree Insert( ElementType X, AvlTree T )
{ if ( T == NULL ) { /* Create and return a one-node tree */
T = malloc( sizeof( struct AvlNode ) );
if ( T == NULL ) FatalError( "Out of space!!!" );
else { T->Element = X; T->Height = 0; T->Left = T->Right = NULL; }
} /* End creating a one-node tree */
else if ( X < T->Element ) { /* handle left insertion */
T->Left = Insert( X, T->Left );
if ( Height( T->Left ) - Height( T->Right ) == 2 ) /* not balanced */
if ( X < T->Left->Element ) /* LL Rotation */
T = SingleRotateWithLeft( T );
else /* LR Rotation */
T = DoubleRotateWithLeft( T ); } /* End left */
else if( X > T->Element ) { /* handle right insertion */
T->Right = Insert( X, T->Right );
if ( Height( T->Right ) - Height( T->Left ) == 2 ) /* not balanced */
if ( X > T->Right->Element ) /* RR Rotation */
T = SingleRotateWithRight( T );
else /* RL Rotation */
T = DoubleRotateWithRight( T ); } /* End right */
/* Else X is in the tree already; we'll do nothing */
T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
return T;
}

Home work:

p.136 4.16
Create an AVL Tree
p.136 4.22
Double Rotation

21/22

§4 AVL Trees

Let nh be the minimum number of nodes in a height balanced tree of
height h. Then the tree must look like

A
h2

A
h1

last question:
OROne
h1
h2  nh = nh1 + nh2 + 1

Obviously we have Tp = O( h )
where h is the height of the tree.
But h = ?

Fibonacci numbers:
F0 = 0, F1 = 1, Fi = Fi1 + Fi2 for i > 1
 nh = Fh+2  1, for h  0
i


1  1 5 
Fibonacci number theory gives that Fi 


1  1  5 
 nh 
5  2 
22/22

5

h 2

1

 h  O(lnn)

2