C++ Classes and Data Structures
Jeffrey S. Childs
Chapter 13
Recursion
Jeffrey S. Childs
Clarion University of PA
© 2008, Prentice Hall
1
Recursive Functions
• Recursive functions are functions that
call themselves
• Data structures, especially linked
implementations of binary trees,
sometimes use recursive functions
2
Example: Factorial Function
• The factorial function is often written as a
recursive function
• The factorial of a positive integer is the
product of all positive integers less than or
equal to the number
5 factorial is written 5!
5! = 5 * 4 * 3 * 2 * 1 = 120
3! = 3 * 2 * 1 = 6
0! is defined to be 1
3
Factorial Function
1
2
3
4
5
6
int factorial( int num )
{
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
jump
4
Factorial Function
1
2
3
4
5
6
int factorial( int num )
{
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
The recursive function call
5
What Happens When
a Function Calls Itself?
• When a function calls itself, it is not
actually executing itself again
• Instead, another function is made which is
identical
• Then, that function is called from the
recursive function call
• This will be illustrated in the slides that
follow…
6
Recursive Process
x = factorial( 4 );
A function call that should produce
24 as a result and assign it to x.
7
Recursive Process
(cont.)
x = factorial( 4 );
4 is passed into num
int factorial( int num )
{
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
8
Recursive Process
(cont.)
x = factorial( 4 );
4 replaces each
int factorial( int num )
occurrence of num
{ 4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
4
4
9
Recursive Process
(cont.)
x = factorial( 4 );
int factorial( int num )
{ 4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
4
4
10
Recursive Process
(cont.)
x = factorial( 4 );
int factorial( int num )
{ 4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
4
4
11
Recursive Process
(cont.)
x = factorial( 4 );
int factorial( int num )
{ 4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
12
Recursive Process
(cont.)
x = factorial( 4 );
int factorial( int num )
{ 4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
13
Recursive Process
(cont.)
x = factorial( 4 );
int factorial( int num )
{ 4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
A recursive function call
is made – an identical
factorial function is made
and called.
14
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
15
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
16
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
3 is passed into num
int factorial( int num )
{
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
17
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
3 replaces each
occurrence of num
int factorial( int num )
{ 3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
3
3
18
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{ 3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
3
3
19
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{ 3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
3
3
20
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{ 3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 2 );
}
3
21
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{ 3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 2 );
}
3
22
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{ 3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 2 );
}
3
A recursive function
call is made – an
identical factorial
function is made
and called.
23
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 2 );
}
3
24
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 2 );
}
3
25
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
int factorial( int num )
{
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
2 gets passed into num
return num * factorial( 2 );
}
3
26
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 2 );
}
3
int factorial( int num )
{ 2
2
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
2
2
2 replaces each
occurrence of num
27
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{ 2
2
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
2
2
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 2 );
}
3
28
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{ 2
2
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
2
2
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 2 );
}
3
29
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{ 2
2
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 1 );
}
2
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 2 );
}
3
30
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{ 2
2
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 1 );
}
2
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 2 );
}
3
31
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 2 );
}
3
int factorial( int num )
{ 2
2
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 1 );
}
2
A recursive function
call is made – an
identical factorial
function is made and
called.
32
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
2
2
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 1 );
}
2
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 2 );
}
3
33
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 2 );
}
3
int factorial( int num )
{
2
2
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 1 );
}
2
int factorial( int num )
{
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
34
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 2 );
}
3
int factorial( int num )
{
2
2
if ( num == 0 || num == 1 )
return 1;
1 is
passed
into num
return num * factorial( 1 );
}
2
int factorial( int num )
{
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
35
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 2 );
}
3
int factorial( int num )
{
2
2
if ( num == 0 || num == 1 )
return 1;
1 is
passed
into num
return num * factorial( 1 );
}
2
int factorial( int num )
{ 1
1
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
1
1
}
36
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 2 );
}
3
int factorial( int num )
{
2
2
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 1 );
}
2
int factorial( int num )
{ 1
1
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
1
1
}
37
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 2 );
}
3
int factorial( int num )
{
2
2
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 1 );
}
2
int factorial( int num )
{ 1
1
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
1
1
}
38
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 2 );
}
3
int factorial( int num )
{
2
2
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 1 );
}
2
int factorial( int num )
{ 1
1
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
1
1
}
39
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 2 );
}
3
int factorial( int num )
{
2
2
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 1 );
}
2
int factorial( int num )
{
1
1
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
1
1
40
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 2 );
}
3
int factorial( int num )
{
2
2
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 1 );
}
2
int factorial( int num )
{
1
1
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
1
1
Where is 1 returned?
41
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
int factorial( int num )
{
2
2
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 1 );
}
2
int factorial( int num )
{
1
1
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
return num * factorial(
2
);
The 1 replaces
the1 function call
that
}
1
}
3
called this function (just as we would
expect with any function call)
42
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 2 );
}
3
int factorial( int num )
{
2
2
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 1 );
}
2
int factorial( int num )
{
1
1
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
1
1
43
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 2 );
}
3
int factorial( int num )
{
2
2
if ( num == 0 || num == 1 )
return 1;
return num * 1;
}
2
int factorial( int num )
{
1
1
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
1
1
44
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 2 );
}
3
int factorial( int num )
{
2
2
if ( num == 0 || num == 1 )
return 1;
return num * 1;
}
2
int factorial( int num )
{
1
1
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
1
1
The last function has finished
45
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
2
2
if ( num == 0 || num == 1 )
return 1;
return num * 1;
}
2
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 2 );
}
3
46
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
int factorial( int num )
{
2
2
if ( num == 0 || num == 1 )
return 1;
return num * 1;
}
2
The execution of this
return statement can now
resume
return num * factorial( 2 );
}
3
47
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
int factorial( int num )
{
2
2
if ( num == 0 || num == 1 )
return 1;
return 2;
}
The execution of this
return statement can now
resume
return num * factorial( 2 );
}
3
48
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
int factorial( int num )
{
2
2
if ( num == 0 || num == 1 )
return 1;
return 2;
}
It now returns 2 back to
the function call that
called this function.
return num * factorial( 2 );
}
3
49
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
2
2
if ( num == 0 || num == 1 )
return 1;
return 2;
}
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 2 );
}
3
50
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
2
2
if ( num == 0 || num == 1 )
return 1;
return 2;
}
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 2 );
}
3
51
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
2
2
if ( num == 0 || num == 1 )
return 1;
return 2;
}
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 2 );
}
3
52
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
2
2
if ( num == 0 || num == 1 )
return 1;
return 2;
}
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return num * 2;
}
3
53
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return num * 2;
}
3
54
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return num * 2;
}
3
55
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return 6;
}
56
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return 6;
}
57
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * factorial( 3 );
}
4
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return 6;
}
58
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * 6;
}
4
int factorial( int num )
{
3
3
if ( num == 0 || num == 1 )
return 1;
return 6;
}
59
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * 6;
}
4
60
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return num * 6;
}
4
61
x = factorial( 4 );
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return 24;
}
62
Recursive Process
(cont.)
x = factorial( 4 );
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return 24;
}
63
Recursive Process
(cont.)
x = factorial( 4 );
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return 24;
}
64
Recursive Process
(cont.)
x = factorial( 4 );
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return 24;
x gets the correct
value of 24
}
65
x = 24;
Recursive Process
(cont.)
int factorial( int num )
{
4
4
if ( num == 0 || num == 1 )
return 1;
return 24;
x gets the correct
value of 24
}
66
x = 24;
Recursive Process
(cont.)
67
Base Case
1
2
3
4
5
6
int factorial( int num )
{
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
Notice that these
lines stopped the
recursion – without
these lines, the
function will call
itself over and over
again (infinite
recursion)
68
Base Case (cont.)
1
2
3
4
5
6
int factorial( int num )
{
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
These lines are
called the base
case – the case
that stops the
recursion
69
Recursive Case
1
2
3
4
5
6
int factorial( int num )
{
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
This line that produces a recursive function call
is called the recursive case.
All recursive functions have a base case and a
recursive case (and sometimes more than one
of each).
70
What If?
1
2
3
4
5
6
int factorial( int num )
{
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
If one makes a mistake and inputs a negative
number into this function:
factorial( -2 );
what will happen?
71
Infinite Recursion
1
2
3
4
5
6
int factorial( int num )
{
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
If one makes a mistake and inputs a negative
number into this function:
factorial( -2 );
what will happen? Infinite recursion.
72
Drivers
1
2
3
4
5
6
int factorial( int num )
{
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
In order to prevent this problem, we can change
the name of this function to factorial 2…
73
Drivers
1
2
3
4
5
6
int factorial( int num )
{
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
In order to prevent this problem, we can change
the name of this function to factorial 2…
74
Drivers (cont.)
1
2
3
4
5
6
int factorial2( int num )
{
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
In order to prevent this problem, we can change
the name of this function to factorial2…
75
Drivers (cont.)
1
2
3
4
5
6
int factorial2( int num )
{
if ( num == 0 || num == 1 )
return 1;
return num * factorial( num – 1 );
}
In order to prevent this problem, we can change
the name of this function to factorial2…
76
Drivers (cont.)
1
2
3
4
5
6
int factorial2( int num )
{
if ( num == 0 || num == 1 )
return 1;
return num * factorial2( num – 1 );
}
In order to prevent this problem, we can change
the name of this function to factorial2…
77
Drivers (cont.)
1
2
3
4
5
6
int factorial2( int num )
{
if ( num == 0 || num == 1 )
return 1;
return num * factorial2( num – 1 );
}
and then write a factorial function, called a driver,
to call this function…
78
Drivers (cont.)
int factorial( int num )
{
if ( num < 0 ) {
cout <<
“The factorial of a negative number is undefined”
<< endl;
return 0;
}
return factorial2( num );
}
79
Guidelines
• There must be a base case that stops recursion
• Each recursive call should approach the base
case
• The recursive function call should work for the
base case
• The recursive function call should work for the
case next to the base case
• The recursive function should make logical
sense, assuming that the recursive function call
inside it does everything it should do
80
Example
• When you know the case next to the base
case works, you know factorial( 2 ) works
• Since 3! = 3 * factorial( 2 ), you know
factorial( 3 ) works – makes logical sense
• Since 4! = 4 * factorial( 3 ) and you know
that factorial( 3 ) works, you know that
factorial( 4 ) works
• Etc., etc.
81
Recursion on a
Linked List
Car search( Node<Car> *ptr, Car mercedes )
{
if ( ptr->info == mercedes )
return ptr->info;
return search( ptr->next, mercedes );
}
For use when we know Mercedes is in a linked list
Initial call:
Car auto = search( start, mercedes );
82
Recursion on a
Linked List (cont.)
Car search( Node<Car> *ptr, Car mercedes )
{
if ( ptr->info == mercedes )
Overloaded
return ptr->info;
operator in Car
return search( ptr->next, mercedes );
struct
}
83
Recursion on a
Linked List (cont.)
Car search( Node<Car> *ptr, Car mercedes )
{
if ( ptr->info == mercedes )
return ptr->info;
Advances pointer in
return search( ptr->next, mercedes ); a recursive function
}
call
Car search( Node<Car> *ptr, Car mercedes )
{
if ( ptr->info == mercedes )
return ptr->info;
return search( ptr->next, mercedes );
}
84
Recursion on a
Linked List (cont.)
bool search( Node<Car> *ptr, Car & auto, Car mercedes )
{
if ( ptr == NULL )
return false;
if ( ptr->info == mercedes ) {
auto = ptr->info;
return true;
}
return search( ptr->next, auto, mercedes );
}
For use when we are not sure there is a
Mercedes in the linked list.
85
Recursion on a
Linked List (cont.)
bool search( Node<Car> *ptr, Car & auto, Car mercedes )
{
if ( ptr == NULL )
return false;
if ( ptr->info == mercedes ) {
auto = ptr->info;
return true;
}
return search( ptr->next, auto, mercedes );
}
Returns true if in list; returns false otherwise.
86
Recursion on a
Linked List (cont.)
bool search( Node<Car> *ptr, Car & auto, Car mercedes )
{
if ( ptr == NULL )
If true is returned,
return false;
auto will be assigned
if ( ptr->info == mercedes ) { Mercedes (passed by
auto = ptr->info;
reference on each
return true;
recursive call)
}
return search( ptr->next, auto, mercedes );
}
87
Recursion on a
Linked List (cont.)
bool search( Node<Car> *ptr, Car & auto, Car mercedes )
{
if ( ptr == NULL )
Two
return false;
base
if ( ptr->info == mercedes ) {
cases
auto = ptr->info;
return true;
}
return search( ptr->next, auto, mercedes );
}
88
Recursion on a
Linked List (cont.)
bool search( Node<Car> *ptr, Car & auto, Car mercedes )
{
if ( ptr == NULL )
return false;
if ( ptr->info == mercedes ) {
auto = ptr->info;
return true;
}
return search( ptr->next, auto, mercedes );
}
Don’t forget the return ( it is a common mistake)…
89
Recursion on a
Linked List (cont.)
bool search( Node<Car> *ptr, Car & auto, Car mercedes )
{
if ( ptr == NULL )
return false;
if ( ptr->info == mercedes ) {
auto = ptr->info;
return true;
}
return search( ptr->next, auto, mercedes );
}
It passes the true/false value (from base cases) back
through the succession of recursive function calls.
90
Recursion on a
Linked List (cont.)
1
2
3
4
5
6
7
void discount( Node<Car> *ptr )
{
if ( ptr != NULL ) {
ptr->info.price -= 0.1 * ( ptr->info.price );
discount( ptr->next );
}
}
Discounts all auto prices in a linked list by 10%
91
Recursion on a
Linked List (cont.)
1
2
3
4
5
6
7
void discount( Node<Car> *ptr )
{
if ( ptr != NULL ) {
ptr->info.price -= 0.1 * ( ptr->info.price );
discount( ptr->next );
}
}
Recursive call – no return necessary (void return type)
92
Recursion on a
Linked List (cont.)
1
2
3
4
5
6
7
void discount( Node<Car> *ptr )
{
if ( ptr != NULL ) {
ptr->info.price -= 0.1 * ( ptr->info.price );
discount( ptr->next );
}
}
Where is the base case?
93
Recursion on Linked Lists (cont.)
1
2
3
4
5
6
7
void discount( Node<Car> *ptr )
{
if ( ptr != NULL ) {
ptr->info.price -= 0.1 * ( ptr->info.price );
discount( ptr->next );
}
}
The base case exists, it just does not need to be written.
When ptr == NULL, it is the base case. The only thing that
needs to be done for the base case is to return.
94
Time Complexities
for Recursion
• Recursion is an alternative to a loop
• Recursion is never necessary – anything
that can be done with recursion can be
done with a loop
• Just as we would estimate how many
times a loop iterates, we must estimate
how many times a recursive function is
called – this gives the time complexity
95
Time Complexities
for Recursion (cont.)
1
2
3
4
5
6
7
void discount( Node<Car> *ptr )
{
if ( ptr != NULL ) {
ptr->info.price -= 0.1 * ( ptr->info.price );
discount( ptr->next );
}
This function is called recursively, once for
}
each of the n elements in a linked list, plus
one more time for when ptr == NULL, giving
us a total number of n + 1 calls –
its time complexity, therefore, is ( n )
96
Merge sort
(slides added by niinimakim)
• https://en.wikipedia.org/wiki/Merge_sort by
J. von Neumann 1945
• Idea: divide the array until the sorting is
reduced to swapping 2 adjacent elements
(if needed), then bring back (=merge) the
sorted parts.
• Top-down implementations almost always
use recursion.
• In this implemention we use a tmp array
97
for copying (wastes memory).
Merge sort (cont.)
98
Merge Sort (cont.)
A “driver” that creates a temporary array
where we copy the result in actual sort
function M_Sort
template <class Etype>
void Merge_Sort(Etype A[], int N)
{
Etype *Tmp_Array = new Etype[N+1];
int New_N = N;
M_Sort(A, Tmp_Array, 0, New_N);
delete [] Tmp_Array;
}
99
Merge Sort (cont.)
template <class Etype>
void M_Sort( Etype A[], Etype Tmp_Array[], int Left, int Right)
{
int Center;
if (Left < Right)
{
Center = (Left + Right)/2;
M_Sort(A,Tmp_Array,Left,Center);
M_Sort(A,Tmp_Array,Center+1,Right);
Merge(A, Tmp_Array, Left, Center+1, Right);
}
We know both sides have been sorted so we
}
merge them into Tmp_Array
100
Merge Sort (cont.)
template <class Etype>
void M_Sort( Etype A[], Etype Tmp_Array[], int Left, int Right)
{
int Center;
if (Left < Right)
{
Center = (Left + Right)/2;
M_Sort(A,Tmp_Array,Left,Center);
M_Sort(A,Tmp_Array,Center+1,Right);
Merge(A, Tmp_Array, Left, Center+1, Right);
}
We know both sides have been sorted so we
}
merge them into Tmp_Array
101
Merge Sort (cont.)
The real thing happens in function Merge.
void Merge(Etype A[], Etype Tmp_Array[], int
Left_Pos, int Right_Pos, int Right_End)
L
R
Left_Pos Right_Pos-1 Right_Pos
Right_End
C
We know that the contents of L is sorted,
so is R. But we do not know if L should
come before or after R in C (=combined).
102
Merge Sort (cont.)
template <class Etype>
void Merge(Etype A[], Etype Tmp_Array[], int Left_Pos,
int Right_Pos, int Right_End) {
int Left_End = Right_Pos-1; int Tmp_Pos = Left_Pos;
int Num_Elements = Right_End - Left_Pos +1;
while ((Left_Pos <= Left_End) && (Right_Pos <= Right_End)) {
if (A[Left_Pos] <= A[Right_Pos]) {
Tmp_Array[Tmp_Pos] = A[Left_Pos]; Tmp_Pos++; Left_Pos++;
} else {
Tmp_Array[Tmp_Pos] = A[Right_Pos];
Tmp_Pos++; Right_Pos++;
}
}
//copy the rest without comparison
//finally put everyting from Tmp_Array to A
103
Merge Sort (cont.)
• Code example available at
http://sjoki.uta.fi/~man/mergesort_example
.cpp
• In this top-down, recursive merge sort (n
* lg(n)) both in best case and worst case.
Natural merge sort is a bottom-up method
where we exploit sorted sequences. If the
entire array is already sorted (best case),
we need to traverse it only once: (n)
104
© Copyright 2026 Paperzz