Exercise 4 Recursion
Functions – a short reminder a group of variables and statements that is assigned a name a sub-program inside main we can call other functions These functions can call other functions.
Another way of looking at factorial 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
A recursive definition C functions can also call themselves! However, usually 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 has a “boundary condition”. The function stops calling itself when it is satisfied. Why is this necessary?
Example - factorial int factRec(int n) { if (n==0 || n==1) return 1; return n*factRec(n-1); } int factorial(int n) { int fact = 1; while (n >= 1) { fact *=n; n--; } return fact; }
Recursive factorial – step by step int factRec(int n) { if (n==0 || n==1) return 1; return n*factRec(n-1); } FactRec(4) n 4 Returns…
Recursive factorial – step by step FactRec(4) n 4 Returns… 4*… int factRec(int n) { if (n==0 || n==1) return 1; return n*factRec(n-1); }
Recursive factorial – step by step FactRec(4) n 4 Returns… FactRec(3) n 3 Returns… int factRec(int n) { if (n==0 || n==1) return 1; return n*factRec(n-1); }
Recursive factorial – step by step FactRec(4) n 4 Returns… FactRec(3) n 3 Returns… int factRec(int n) { if (n==0 || n==1) return 1; return n*factRec(n-1); }
Recursive factorial – step by step FactRec(4) n 4 Returns… FactRec(3) n 3 Returns… 3*… int factRec(int n) { if (n==0 || n==1) return 1; return n*factRec(n-1); }
Recursive factorial – step by step FactRec(4) n 4 Returns… FactRec(3) n 3 Returns… FactRec(2) n 2 Returns… int factRec(int n) { if (n==0 || n==1) return 1; return n*factRec(n-1); }
Recursive factorial – step by step FactRec(4) n 4 Returns… FactRec(3) n 3 Returns… FactRec(2) n 2 Returns… int factRec(int n) { if (n==0 || n==1) return 1; return n*factRec(n-1); }
Recursive factorial – step by step FactRec(4) n 4 Returns… FactRec(3) n 3 Returns… FactRec(2) n 2 Returns… 2*… int factRec(int n) { if (n==0 || n==1) return 1; return n*factRec(n-1); }
Recursive factorial – step by step FactRec(4) n 4 Returns… FactRec(3) n 3 Returns… FactRec(2) n 2 Returns… FactRec(1) n 1 Returns… int factRec(int n) { if (n==0 || n==1) return 1; return n*factRec(n-1); }
Recursive factorial – step by step FactRec(4) n 4 Returns… FactRec(3) n 3 Returns… FactRec(2) n 2 Returns… FactRec(1) n 1 Returns… int factRec(int n) { if (n==0 || n==1) return 1; return n*factRec(n-1); }
Recursive factorial – step by step FactRec(4) n 4 Returns… FactRec(3) n 3 Returns… FactRec(2) n 2 Returns… FactRec(1) n 1 Returns… 1 int factRec(int n) { if (n==0 || n==1) return 1; return n*factRec(n-1); }
Recursive factorial – step by step FactRec(4) n 4 Returns… FactRec(3) n 3 Returns… FactRec(2) n 2 Returns… 2*1 int factRec(int n) { if (n==0 || n==1) return 1; return n*factRec(n-1); }
Recursive factorial – step by step FactRec(4) n 4 Returns… FactRec(3) n 3 Returns… 3*2 int factRec(int n) { if (n==0 || n==1) return 1; return n*factRec(n-1); }
Recursive factorial – step by step FactRec(4) n 4 Returns… 4*6 int factRec(int n) { if (n==0 || n==1) return 1; return n*factRec(n-1); }
Another example - power X y = x*x*…*x Recursive definitions (assume non- negative y): Base: x 0 =1 1. X y = X*(X y-1 ) 2. X y = (X y/2 ) 2 (for even y ’s only) y times
Example rec_pow.c
rec_pow – step by step int rec_pow(int x, int y) { if (y == 0) return 1; if (y%2 == 0) return square(rec_pow(x,y/2)); else return x*rec_pow(x,y-1); } rec_pow(2, 5) x 2 Returns… y 5
rec_pow – step by step rec_pow(2, 5) x 2 Returns… y 5 int rec_pow(int x, int y) { if (y == 0) return 1; if (y%2 == 0) return square(rec_pow(x,y/2)); else return x*rec_pow(x,y-1); }
rec_pow – step by step int rec_pow(int x, int y) { if (y == 0) return 1; if (y%2 == 0) return square(rec_pow(x,y/2)); else return x*rec_pow(x,y-1); } rec_pow(2, 5) x 2 Returns… y 5
rec_pow – step by step int rec_pow(int x, int y) { if (y == 0) return 1; if (y%2 == 0) return square(rec_pow(x,y/2)); else return x*rec_pow(x,y-1); } rec_pow(2, 5) x 2 Returns… y 5
rec_pow – step by step rec_pow(2, 5) x 2 Returns… 2*… y 5 int rec_pow(int x, int y) { if (y == 0) return 1; if (y%2 == 0) return square(rec_pow(x,y/2)); else return x*rec_pow(x,y-1); }
int rec_pow(int x, int y) { if (y == 0) return 1; if (y%2 == 0) return square(rec_pow(x,y/2)); else return x*rec_pow(x,y-1); } rec_pow(2, 5) x 2 Returns… y 5 rec_pow – step by step rec_pow(2, 4) x 2 Returns… y 4
rec_pow – step by step int rec_pow(int x, int y) { if (y == 0) return 1; if (y%2 == 0) return square(rec_pow(x,y/2)); else return x*rec_pow(x,y-1); } rec_pow(2, 5) x 2 Returns… y 5 rec_pow(2, 4) x 2 Returns… y 4
rec_pow – step by step int rec_pow(int x, int y) { if (y == 0) return 1; if (y%2 == 0) return square(rec_pow(x,y/2)); else return x*rec_pow(x,y-1); } rec_pow(2, 5) x 2 Returns… y 5 rec_pow(2, 4) x 2 Returns… y 4
rec_pow – step by step int rec_pow(int x, int y) { if (y == 0) return 1; if (y%2 == 0) return square(rec_pow(x,y/2)); else return x*rec_pow(x,y-1); } rec_pow(2, 5) x 2 Returns… y 5 rec_pow(2, 4) x 2 Returns… square(…) y 4
rec_pow – step by step int rec_pow(int x, int y) { if (y == 0) return 1; if (y%2 == 0) return square(rec_pow(x,y/2)); else return x*rec_pow(x,y-1); } rec_pow(2, 5) x 2 Returns… y 5 rec_pow(2, 4) x 2 Returns… square(…) y 4 rec_pow(2, 2) x 2 Returns… y 2
rec_pow – step by step int rec_pow(int x, int y) { if (y == 0) return 1; if (y%2 == 0) return square(rec_pow(x,y/2)); else return x*rec_pow(x,y-1); } rec_pow(2, 5) x 2 Returns… y 5 rec_pow(2, 4) x 2 Returns… square(…) y 4 rec_pow(2, 2) x 2 Returns… y 2
rec_pow – step by step int rec_pow(int x, int y) { if (y == 0) return 1; if (y%2 == 0) return square(rec_pow(x,y/2)); else return x*rec_pow(x,y-1); } rec_pow(2, 5) x 2 Returns… y 5 rec_pow(2, 4) x 2 Returns… square(…) y 4 rec_pow(2, 2) x 2 Returns… y 2
rec_pow – step by step int rec_pow(int x, int y) { if (y == 0) return 1; if (y%2 == 0) return square(rec_pow(x,y/2)); else return x*rec_pow(x,y-1); } rec_pow(2, 5) x 2 Returns… y 5 rec_pow(2, 4) x 2 Returns… square(…) y 4 rec_pow(2, 2) x 2 Returns… square(…) y 2
rec_pow – step by step int rec_pow(int x, int y) { if (y == 0) return 1; if (y%2 == 0) return square(rec_pow(x,y/2)); else return x*rec_pow(x,y-1); } rec_pow(2, 5) x 2 Returns… y 5 rec_pow(2, 4) x 2 Returns… square(…) y 4 rec_pow(2, 2) x 2 Returns… square(…) y 2 rec_pow(2, 1) x 2 Returns… y 1
rec_pow – step by step int rec_pow(int x, int y) { if (y == 0) return 1; if (y%2 == 0) return square(rec_pow(x,y/2)); else return x*rec_pow(x,y-1); } rec_pow(2, 5) x 2 Returns… y 5 rec_pow(2, 4) x 2 Returns… square(…) y 4 rec_pow(2, 2) x 2 Returns… square(…) y 2 rec_pow(2, 1) x 2 Returns… y 1
rec_pow – step by step int rec_pow(int x, int y) { if (y == 0) return 1; if (y%2 == 0) return square(rec_pow(x,y/2)); else return x*rec_pow(x,y-1); } rec_pow(2, 5) x 2 Returns… y 5 rec_pow(2, 4) x 2 Returns… square(…) y 4 rec_pow(2, 2) x 2 Returns… square(…) y 2 rec_pow(2, 1) x 2 Returns… y 1
rec_pow – step by step int rec_pow(int x, int y) { if (y == 0) return 1; if (y%2 == 0) return square(rec_pow(x,y/2)); else return x*rec_pow(x,y-1); } rec_pow(2, 5) x 2 Returns… y 5 rec_pow(2, 4) x 2 Returns… square(…) y 4 rec_pow(2, 2) x 2 Returns… square(…) y 2 rec_pow(2, 1) x 2 Returns… y 1
rec_pow – step by step int rec_pow(int x, int y) { if (y == 0) return 1; if (y%2 == 0) return square(rec_pow(x,y/2)); else return x*rec_pow(x,y-1); } rec_pow(2, 5) x 2 Returns… y 5 rec_pow(2, 4) x 2 Returns… square(…) y 4 rec_pow(2, 2) x 2 Returns… square(…) y 2 rec_pow(2, 1) x 2 Returns… 2*… y 1
rec_pow – step by step int rec_pow(int x, int y) { if (y == 0) return 1; if (y%2 == 0) return square(rec_pow(x,y/2)); else return x*rec_pow(x,y-1); } rec_pow(2, 5) x 2 Returns… y 5 rec_pow(2, 4) x 2 Returns… square(…) y 4 rec_pow(2, 2) x 2 Returns… square(…) y 2 rec_pow(2, 1) x 2 Returns… 2*… y 1 rec_pow(2, 0) x 2 Returns… y 0
rec_pow – step by step int rec_pow(int x, int y) { if (y == 0) return 1; if (y%2 == 0) return square(rec_pow(x,y/2)); else return x*rec_pow(x,y-1); } rec_pow(2, 5) x 2 Returns… y 5 rec_pow(2, 4) x 2 Returns… square(…) y 4 rec_pow(2, 2) x 2 Returns… square(…) y 2 rec_pow(2, 1) x 2 Returns… 2*… y 1 rec_pow(2, 0) x 2 Returns… y 0
rec_pow – step by step int rec_pow(int x, int y) { if (y == 0) return 1; if (y%2 == 0) return square(rec_pow(x,y/2)); else return x*rec_pow(x,y-1); } rec_pow(2, 5) x 2 Returns… y 5 rec_pow(2, 4) x 2 Returns… square(…) y 4 rec_pow(2, 2) x 2 Returns… square(…) y 2 rec_pow(2, 1) x 2 Returns… 2*… y 1 rec_pow(2, 0) x 2 Returns… 1 y 0
rec_pow – step by step int rec_pow(int x, int y) { if (y == 0) return 1; if (y%2 == 0) return square(rec_pow(x,y/2)); else return x*rec_pow(x,y-1); } rec_pow(2, 5) x 2 Returns… y 5 rec_pow(2, 4) x 2 Returns… square(…) y 4 rec_pow(2, 2) x 2 Returns… square(…) y 2 rec_pow(2, 1) x 2 Returns… 2*1 y 1
rec_pow – step by step int rec_pow(int x, int y) { if (y == 0) return 1; if (y%2 == 0) return square(rec_pow(x,y/2)); else return x*rec_pow(x,y-1); } rec_pow(2, 5) x 2 Returns… y 5 rec_pow(2, 4) x 2 Returns… square(…) y 4 rec_pow(2, 2) x 2 Returns… square(2) y 2
rec_pow – step by step int rec_pow(int x, int y) { if (y == 0) return 1; if (y%2 == 0) return square(rec_pow(x,y/2)); else return x*rec_pow(x,y-1); } rec_pow(2, 5) x 2 Returns… y 5 rec_pow(2, 4) x 2 Returns… square(4) y 4
rec_pow – step by step int rec_pow(int x, int y) { if (y == 0) return 1; if (y%2 == 0) return square(rec_pow(x,y/2)); else return x*rec_pow(x,y-1); } rec_pow(2, 5) x 2 Returns… 2*16 y 5
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 rec_mul.c
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; }
Solution sum_digit_rec.c
More uses Recursion is a general approach to programming functions Its uses are not confined to calculating mathematical expressions! For example – max_rec.c
max_rec – step by step int rec_max(int arr[ ], int size) { int rest; if (size == 1) return arr[0]; else { rest = rec_max(arr+1, size-1); if (arr[0] > rest) return arr[0]; else return rest; } rec_max(752, 4) rest … Returns… arr 752 size 4
max_rec – step by step rec_max(752, 4) rest … Returns… arr 752 size 4 int rec_max(int arr[ ], int size) { int rest; if (size == 1) return arr[0]; else { rest = rec_max(arr+1, size-1); if (arr[0] > rest) return arr[0]; else return rest; }
max_rec – step by step rec_max(752, 4) rest … Returns… arr 752 size 4 int rec_max(int arr[ ], int size) { int rest; if (size == 1) return arr[0]; else { rest = rec_max(arr+1, size-1); if (arr[0] > rest) return arr[0]; else return rest; }
max_rec – step by step rec_max(752, 4) rest … Returns… arr 752 size 4 int rec_max(int arr[ ], int size) { int rest; if (size == 1) return arr[0]; else { rest = rec_max(arr+1, size-1); if (arr[0] > rest) return arr[0]; else return rest; }
max_rec – step by step rec_max(752, 4) rest … Returns… arr 752 size 4 rec_max(756, 3) rest … Returns… arr 756 size 3 int rec_max(int arr[ ], int size) { int rest; if (size == 1) return arr[0]; else { rest = rec_max(arr+1, size-1); if (arr[0] > rest) return arr[0]; else return rest; }
max_rec – step by step rec_max(752, 4) rest … Returns… arr 752 size 4 rec_max(756, 3) rest … Returns… arr 756 size 3 int rec_max(int arr[ ], int size) { int rest; if (size == 1) return arr[0]; else { rest = rec_max(arr+1, size-1); if (arr[0] > rest) return arr[0]; else return rest; }
max_rec – step by step rec_max(752, 4) rest … Returns… arr 752 size 4 rec_max(756, 3) rest … Returns… arr 756 size 3 int rec_max(int arr[ ], int size) { int rest; if (size == 1) return arr[0]; else { rest = rec_max(arr+1, size-1); if (arr[0] > rest) return arr[0]; else return rest; }
max_rec – step by step rec_max(752, 4) rest … Returns… arr 752 size 4 rec_max(756, 3) rest … Returns… arr 756 size 3 int rec_max(int arr[ ], int size) { int rest; if (size == 1) return arr[0]; else { rest = rec_max(arr+1, size-1); if (arr[0] > rest) return arr[0]; else return rest; }
max_rec – step by step rec_max(752, 4) rest … Returns… arr 752 size 4 rec_max(756, 3) rest … Returns… arr 756 size 3 rec_max(760, 2) rest … Returns… arr 760 size 2 int rec_max(int arr[ ], int size) { int rest; if (size == 1) return arr[0]; else { rest = rec_max(arr+1, size-1); if (arr[0] > rest) return arr[0]; else return rest; }
max_rec – step by step rec_max(752, 4) rest … Returns… arr 752 size 4 rec_max(756, 3) rest … Returns… arr 756 size 3 rec_max(760, 2) rest … Returns… arr 760 size 2 int rec_max(int arr[ ], int size) { int rest; if (size == 1) return arr[0]; else { rest = rec_max(arr+1, size-1); if (arr[0] > rest) return arr[0]; else return rest; }
max_rec – step by step rec_max(752, 4) rest … Returns… arr 752 size 4 rec_max(756, 3) rest … Returns… arr 756 size 3 rec_max(760, 2) rest … Returns… arr 760 size 2 int rec_max(int arr[ ], int size) { int rest; if (size == 1) return arr[0]; else { rest = rec_max(arr+1, size-1); if (arr[0] > rest) return arr[0]; else return rest; }
max_rec – step by step rec_max(752, 4) rest … Returns… arr 752 size 4 rec_max(756, 3) rest … Returns… arr 756 size 3 rec_max(760, 2) rest … Returns… arr 760 size 2 int rec_max(int arr[ ], int size) { int rest; if (size == 1) return arr[0]; else { rest = rec_max(arr+1, size-1); if (arr[0] > rest) return arr[0]; else return rest; }
max_rec – step by step rec_max(752, 4) rest … Returns… arr 752 size 4 rec_max(756, 3) rest … Returns… arr 756 size 3 rec_max(760, 2) rest … Returns… arr 760 size 2 rec_max(764, 1) rest … Returns… arr 764 size 1 int rec_max(int arr[ ], int size) { int rest; if (size == 1) return arr[0]; else { rest = rec_max(arr+1, size-1); if (arr[0] > rest) return arr[0]; else return rest; }
max_rec – step by step rec_max(752, 4) rest … Returns… arr 752 size 4 rec_max(756, 3) rest … Returns… arr 756 size 3 rec_max(760, 2) rest … Returns… arr 760 size 2 rec_max(764, 1) rest … Returns… arr 764 size 1 int rec_max(int arr[ ], int size) { int rest; if (size == 1) return arr[0]; else { rest = rec_max(arr+1, size-1); if (arr[0] > rest) return arr[0]; else return rest; }
max_rec – step by step rec_max(752, 4) rest … Returns… arr 752 size 4 rec_max(756, 3) rest … Returns… arr 756 size 3 rec_max(760, 2) rest … Returns… arr 760 size 2 rec_max(764, 1) rest … Returns… 3 arr 764 size 1 int rec_max(int arr[ ], int size) { int rest; if (size == 1) return arr[0]; else { rest = rec_max(arr+1, size-1); if (arr[0] > rest) return arr[0]; else return rest; }
max_rec – step by step rec_max(752, 4) rest … Returns… arr 752 size 4 rec_max(756, 3) rest … Returns… arr 756 size 3 rec_max(760, 2) rest 3 Returns… arr 760 size 2 int rec_max(int arr[ ], int size) { int rest; if (size == 1) return arr[0]; else { rest = rec_max(arr+1, size-1); if (arr[0] > rest) return arr[0]; else return rest; }
max_rec – step by step rec_max(752, 4) rest … Returns… arr 752 size 4 rec_max(756, 3) rest … Returns… arr 756 size 3 rec_max(760, 2) rest 3 Returns… arr 760 size 2 int rec_max(int arr[ ], int size) { int rest; if (size == 1) return arr[0]; else { rest = rec_max(arr+1, size-1); if (arr[0] > rest) return arr[0]; else return rest; }
max_rec – step by step rec_max(752, 4) rest … Returns… arr 752 size 4 rec_max(756, 3) rest … Returns… arr 756 size 3 rec_max(760, 2) rest 3 Returns… 5 arr 760 size 2 int rec_max(int arr[ ], int size) { int rest; if (size == 1) return arr[0]; else { rest = rec_max(arr+1, size-1); if (arr[0] > rest) return arr[0]; else return rest; }
max_rec – step by step rec_max(752, 4) rest … Returns… arr 752 size 4 rec_max(756, 3) rest 5 Returns… arr 756 size 3 int rec_max(int arr[ ], int size) { int rest; if (size == 1) return arr[0]; else { rest = rec_max(arr+1, size-1); if (arr[0] > rest) return arr[0]; else return rest; }
max_rec – step by step rec_max(752, 4) rest … Returns… arr 752 size 4 rec_max(756, 3) rest 5 Returns… arr 756 size 3 int rec_max(int arr[ ], int size) { int rest; if (size == 1) return arr[0]; else { rest = rec_max(arr+1, size-1); if (arr[0] > rest) return arr[0]; else return rest; }
max_rec – step by step rec_max(752, 4) rest … Returns… arr 752 size 4 rec_max(756, 3) rest 5 Returns… arr 756 size 3 int rec_max(int arr[ ], int size) { int rest; if (size == 1) return arr[0]; else { rest = rec_max(arr+1, size-1); if (arr[0] > rest) return arr[0]; else return rest; }
max_rec – step by step rec_max(752, 4) rest … Returns… arr 752 size 4 rec_max(756, 3) rest 5 Returns… 5 arr 756 size 3 int rec_max(int arr[ ], int size) { int rest; if (size == 1) return arr[0]; else { rest = rec_max(arr+1, size-1); if (arr[0] > rest) return arr[0]; else return rest; }
max_rec – step by step rec_max(752, 4) rest 5 Returns… arr 752 size 4 int rec_max(int arr[ ], int size) { int rest; if (size == 1) return arr[0]; else { rest = rec_max(arr+1, size-1); if (arr[0] > rest) return arr[0]; else return rest; }
max_rec – step by step rec_max(752, 4) rest 5 Returns… arr 752 size 4 int rec_max(int arr[ ], int size) { int rest; if (size == 1) return arr[0]; else { rest = rec_max(arr+1, size-1); if (arr[0] > rest) return arr[0]; else return rest; }
max_rec – step by step rec_max(752, 4) rest 5 Returns… arr 752 size 4 int rec_max(int arr[ ], int size) { int rest; if (size == 1) return arr[0]; else { rest = rec_max(arr+1, size-1); if (arr[0] > rest) return arr[0]; else return rest; }
max_rec – step by step rec_max(752, 4) rest 5 Returns… 5 arr 752 size 4 int rec_max(int arr[ ], int size) { int rest; if (size == 1) return arr[0]; else { rest = rec_max(arr+1, size-1); if (arr[0] > rest) return arr[0]; else return rest; }
Riddle: what does this do? char *rec_func(char str[], char c) { if (*str == '\0') return NULL; if (*str == c) return str; return rec_func(str+1, c); }
Solution A recursive implementation of strchr See strchr_rec.c
Exercise Write a recursive implementation of strcmp – Input – two strings Output – 0 if both are equal, 1 if not Write a program that accepts two strings from the user and checks whether they are equal
Solution strcmp_rec.c