Programming Recursion “To Iterate is Human, to Recurse, Divine” -- L. Peter Deutsch.
-
date post
21-Dec-2015 -
Category
Documents
-
view
222 -
download
3
Transcript of Programming Recursion “To Iterate is Human, to Recurse, Divine” -- L. Peter Deutsch.
Functions – Reminder
A group of variables and statements that is assigned a name
A sub-program A function may call other functions.
return-type name(arg_type1 arg_name1, arg_type2 arg_name2, …)
{
function body;
return value;
}
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
We can call a function from the point in the file in which the function has been declared, until the end of the file.
return-type name(arg_type1 arg_name1, arg_type2 arg_name2, …);
Recursive Function
A function defined in terms of itself is called a recursive function.
return_value rec_func(type arg1, type arg2, …){ … rec_func(…); …}
As we saw, n! = 1*2*3*… *(n-1)*n
Thus, we can also define factorial the following way: 0! = 1 n! = n*(n-1)! for n>0
(n-1)!* n
Factorial
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_rec(int n){ if (n == 0) return 1;
return n * fact_rec(n-1);}
int fact_itr(int n){ int fact = 1;
while (n >= 1) { fact *= n; --n; }
return fact;}
Recursive factorial
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
n ← 4return ← ?
Recursive factorial
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
n ← 4return ← 4 * ?
Recursive factorial
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
n ← 4return ← 4 * ?
n ← 3return ← ?
Recursive factorial
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
n ← 4return ← 4 * ?
n ← 3return ← 3 * ?
Recursive factorial
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
n ← 4return ← 4 * ?
n ← 3return ← 3 * ?
n ← 2return ← ?
Recursive factorial
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
n ← 4return ← 4 * ?
n ← 3return ← 3 * ?
n ← 2return ← 2 * ?
Recursive factorial
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
n ← 4return ← 4 * ?
n ← 3return ← 3 * ?
n ← 2return ← 2 * ?
n ← 1return ← ?
Recursive factorial
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
n ← 4return ← 4 * ?
n ← 3return ← 3 * ?
n ← 2return ← 2 * ?
n ← 1return ← 1 * ?
Recursive factorial
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
n ← 4return ← 4 * ?
n ← 3return ← 3 * ?
n ← 2return ← 2 * ?
n ← 1return ← 1 * ?
n ← 0return ← ?
Recursive factorial
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
n ← 4return ← 4 * ?
n ← 3return ← 3 * ?
n ← 2return ← 2 * ?
n ← 1return ← 1 * ?
n ← 0return ← 1
Recursive factorial
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
n ← 4return ← 4 * ?
n ← 3return ← 3 * ?
n ← 2return ← 2 * ?
n ← 1return ← 1 * 1
Recursive factorial
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
n ← 4return ← 4 * ?
n ← 3return ← 3 * ?
n ← 2return ← 2 * 1
Recursive factorial
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
n ← 4return ← 4 * ?
n ← 3return ← 3 * 2
Recursive factorial
int fact_rec(int n)
{
if (n == 0)
return 1;
return n * fact_rec(n-1);
}
n ← 4return ← 4 * 6
Another Examplevoid print_nums(int num){ if (num == 0) return;
printf("%d ", num); print_nums(num - 1); printf("%d ", num);}
printcall funcprint
3
printcall funcprint
2
printcall funcprint
1
return 0
3 2 1 1 2 3
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
xy = x*x*…*x
Recursive definitions (assume non-negative y): 1, y = 0 xy= x*xy-1, y odd (xy/2)2, y even
y times
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 non-negative 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 sum-of-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;
}
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;}
1 4 7 2arr:
max_rec( , 4)
rest_max =
max_rec( , 3)
rest_max =
max_rec( , 2)
rest_max =
max_rec( , 1)
rest_max =
2
7
7
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);}
Exercise
Give a recursive implementation to int strcmp(const char *s, const char *t);
The function compares two strings and return: 0 – if s == t negative – if s < t positive – if s > t
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 CB
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 CB
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); }}