recursive function

Programming
Recursion
“To Iterate is Human, to Recurse, Divine”
-- L. Peter Deutsch
Functions – Reminder
return-type name(arg_type1 arg_name1, arg_type2 arg_name2, …)
{
function body;
return value;
}
A group of variables and statements
that is assigned a name
 A sub-program

 A function
may call other functions.
Return Statement - Reminder

Return causes the execution of the
function to terminate and returns a
value to the caller.
Scope of Variables - Reminder
A variable declared within a function is
unrelated to variables declared
elsewhere
 A function cannot directly access
variables that are declared in other
functions

Function Declaration - Reminder
return-type name(arg_type1 arg_name1, arg_type2 arg_name2, …);

We can call a function from the point in the
file in which the function has been
declared, until the end of the file.
Recursive Function

A function defined in terms of itself is
called a recursive function.
return_value rec_func(type arg1, type arg2, …)
{
…
rec_func(…);
…
}
Factorial

As we saw, n! = 1*2*3*… *(n-1)*n
(n-1)!* n

Thus, we can also define factorial the
following way:
 0!
=1
 n! = n*(n-1)! for n>0
A Recursive Definition

C functions can call themselves!
 However,



not with the same parameters (why?)
Some functions can be defined using smaller
occurrences of themselves.
Such a definition is called a “recursive definition”
of a function.
Every recursive function must have a “boundary
condition”. The function stops calling itself when
it is satisfied.
 Why
is this necessary?
Example - Factorial
int fact_itr(int n)
{
int fact = 1;
while (n >= 1)
{
fact *= n;
--n;
}
return fact;
}
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
Recursive factorial
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
n←4
return ← ?
Recursive factorial
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
n←4
return ← 4 * ?
Recursive factorial
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
n←4
return ← 4 * ?
n←3
return ← ?
Recursive factorial
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
n←4
return ← 4 * ?
n←3
return ← 3 * ?
Recursive factorial
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
n←4
return ← 4 * ?
n←3
return ← 3 * ?
n←2
return ← ?
Recursive factorial
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
n←4
return ← 4 * ?
n←3
return ← 3 * ?
n←2
return ← 2 * ?
Recursive factorial
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
n←4
return ← 4 * ?
n←3
return ← 3 * ?
n←2
return ← 2 * ?
n←1
return ← ?
Recursive factorial
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
n←4
return ← 4 * ?
n←3
return ← 3 * ?
n←2
return ← 2 * ?
n←1
return ← 1 * ?
Recursive factorial
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
n←4
return ← 4 * ?
n←3
return ← 3 * ?
n←2
return ← 2 * ?
n←1
return ← 1 * ?
n←0
return ← ?
Recursive factorial
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
n←4
return ← 4 * ?
n←3
return ← 3 * ?
n←2
return ← 2 * ?
n←1
return ← 1 * ?
n←0
return ← 1
Recursive factorial
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
n←4
return ← 4 * ?
n←3
return ← 3 * ?
n←2
return ← 2 * ?
n←1
return ← 1 * 1
Recursive factorial
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
n←4
return ← 4 * ?
n←3
return ← 3 * ?
n←2
return ← 2 * 1
Recursive factorial
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
n←4
return ← 4 * ?
n←3
return ← 3 * 2
Recursive factorial
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
n←4
return ← 4 * 6
Another Example
void print_nums(int num)
{
if (num == 0)
return;
printf("%d ", num);
print_nums(num - 1);
printf("%d ", num);
3 2 1 1 2 3
}
3
print
call func
print
2
print
call func
print
1
print
call func
print
return
0
What Does It Do?
void foo()
{
int num;
scanf("%d", &num);
if (num < 0)
return;
foo();
printf("%d ", num);
}
Reverse Print
void reverse_print()
{
int num;
scanf("%d", &num);
if (num < 0)
return;
}
reverse_print();
printf("%d ", num);
Reads an unbounded series of numbers from the
user and prints them in reverse order.
Power

y
x = x*x*…*x
y times

Recursive definitions (assume non-negative y):
1,
y=0
y
y-1
x = x*x , y odd
y/2 2
(x ) , y even
rec_pow
int rec_pow(int x, int y)
{
if (y == 0)
return 1;
if (y % 2 != 0)
return x * rec_pow(x, y - 1);
else
return square(rec_pow(x, y / 2));
}
The Three Rules of Recursion
1. Know when to stop.
2. Decide how to take one step.
3. Break the problem down into that step
plus a smaller problem.
Exercise

Write a program that receives two nonnegative integers and computes their
product recursively.

Hint: Notice that the product a*b is
actually a+a+…+a (b times).
Solution
int rec_mul(int a, int b)
{
/* base condition – a * 0 = 0 */
if (b == 0)
return 0;
/* save a and call recursively */
return a + rec_mul(a, b-1);
}
Exercise

Given the following
iterative version of sumof-digits calculation
Find the recursive
definition of this function
(don’t forget the base
case!)
int sum_digits(int n)
{
int sum = 0;
while (n > 0)
{
sum += n%10;
n = n/10;
}
return sum;
}
Solution
int sum_digit_rec(int n)
{
if (n == 0)
return 0;
return n % 10 + sum_digit_rec(n / 10);
}
More uses
Recursion is a general approach to
programming functions
 Its uses are not confined to calculating
mathematical expressions!
 For example – max_rec.c

Step By Step
int max_rec(int *arr, int size)
{
int rest_max;
if (size == 1)
return *arr;
}
rest_max =
max_rec(arr + 1, size - 1);
if (*arr > rest_max)
return *arr;
else
return rest_max;
arr: 1
4
7
max_rec( , 4)
rest_max = 7
max_rec( , 3)
rest_max = 7
max_rec( , 2)
rest_max = 2
max_rec( , 1)
rest_max =
2
What Does It Do?
char *rec_func(char *str, char c)
{
if (*str == '\0')
return NULL;
if (*str == c)
return str;
return rec_func(++str, c);
}
Solution

A recursive implementation of strchr
Exercise

Give a recursive implementation to
int strcmp(const char *s, const char *t);

The function compares two strings and return:
– if s == t
 negative – if s < t
 positive – if s > t
0

Write a program that accepts two strings from the
user and compare them using the above function
Solution
int strcmp(cons char *s, const char *t)
{
if (*s != *t)
return *s - *t;
if (*s == '\0')
return 0;
return strcmp(++s, ++t);
}
Towers of Hanoi

Initial Setup:
 Tower A contains
n disks of different sizes.
 Disks can only go on top of smaller disks (or
directly on the board).
A
B
C
Towers of Hanoi

Objective:
 Move
all n disks from tower A to tower C.
A
B
C
Towers of Hanoi

Moves:
 Take
the top disk of a tower and move the
disk to another tower.
 No disk may be put on top of a smaller disk.
A
B
C
Towers of Hanoi

Move tower with n disks is equivalent to:
1. Move tower with n-1 disks
A
B
C
Towers of Hanoi

Move tower with n disks is equivalent to:
2. Move a single disk
A
B
C
Towers of Hanoi

Move tower with n disks is equivalent to:
3. Move tower with n-1 disks
A
B
C
Towers of Hanoi - C
void move_disk(char from, char to)
{
printf("move disk from %c to %c\n", from, to);
}
void move_tower(int height, char from, char to, char temp)
{
if (height == 1) {
move_disk(from, to);
} else {
move_tower(height - 1, from, temp, to);
move_disk(from, to);
move_tower(height - 1, temp, to, from);
}
}