Recursion Introduction What does the program do include























![int search(int A[], int size, int value) { int pos; if (size==1) if(A[size-1]==value) pos=1; int search(int A[], int size, int value) { int pos; if (size==1) if(A[size-1]==value) pos=1;](https://slidetodoc.com/presentation_image/356593d313248ad94625749e218ed14c/image-24.jpg)


![int bsearch(int data[], lower, upper, value) { int pos; if (lower<=upper) { mid=(lower+upper)/ 2; int bsearch(int data[], lower, upper, value) { int pos; if (lower<=upper) { mid=(lower+upper)/ 2;](https://slidetodoc.com/presentation_image/356593d313248ad94625749e218ed14c/image-27.jpg)
![(iterative) Binary search: int bsearch(int data[], int size, int value) { int lower, middle, (iterative) Binary search: int bsearch(int data[], int size, int value) { int lower, middle,](https://slidetodoc.com/presentation_image/356593d313248ad94625749e218ed14c/image-28.jpg)






![bool palindrom(int a[], lower, upper) { bool pal=false; if (lower>=upper) pal=true; else pal=(a[lower]==a[upper]) && bool palindrom(int a[], lower, upper) { bool pal=false; if (lower>=upper) pal=true; else pal=(a[lower]==a[upper]) &&](https://slidetodoc.com/presentation_image/356593d313248ad94625749e218ed14c/image-35.jpg)
- Slides: 35
Recursion
Introduction What does the program do? #include <iostream> using namespace std; int fac(int n){ int product; if(n <= 1) product = 1; else product = n * fac(n-1); return product; } void main(){ int number; cout << "Enter a positive integer : " << endl; ; cin >> number; cout << fac(number) << endl; }
Trace it … Assume the number typed is 3. fac(3): has the final returned value 6 3<=1 ? No. product 3 = 3*fac(2) product 3=3*2=6, return 6, fac(2): 2<=1 ? No. product 2 = 2*fac(1) product 2=2*1=2, return 2, fac(1): 1<=1 ? Yes. return 1
Normal (non-recursive) functions Recursive function int main() { one(…); } int main() { fac(3); } void one(…) { … two(…) … } int fac(int n){ int product; if(n <= 1) product = 1; else product = n * fac(n-1); return product; void two(…) { … three(…) … } } void three(…) { … } l l Functions are calling DIFFERENT functions One function (three) is the last ‘stopping function’ l l … calling the SAME function (with different parameters) … The ‘stopping function’ is already included as a ‘condition’
Recursive function A recursive function is just a function which is calling one (or more) other functions which happen to be the same!!! l l Though the function is the same, the ‘parameters’ are always different and ‘smaller’. There is always at least one stopping case to terminate. It is a kind of ‘loop’, even more powerful as a general problem-solving technique! --- thinking recursively!
Recursion: problem solving, therefore a programming technique Remember: The general top-down programming and problem solving: A complex problem is often easier to solve by dividing it into several smaller parts (by top-down analysis), each of which can be solved by itself. * * * Recursion is one way to decompose a task into smaller subtasks. At least one of the subtasks is a smaller example of the same task. The smallest example of the same task has a non-recursive solution. Example: The factorial function n! = n * (n-1) * (n-2) *. . . * 1 or n! = n * (n-1)! and 1! = 1
Recursion vs. Iteration (non-recursive) * A recursive solution may be simpler to write (once you get used to the idea) than a non-recursive solution. * But a recursive solution may not be as efficient as a nonrecursive solution of the same problem. To iterate is human, to recurse, divine!
Iterative Factorial // Non-recursive factorial function // Compute the factorial using a loop int fac(int n){ int k, product; if(n <=1) product = 1; for(k=1; k<=n; k++) product = k*product; return product; }
Other recursive examples * Fibonacci numbers: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, . . . where each number is the sum of the preceding two. * Recursive definition: F(0) = 0 n F(1) = 1 n F(n) = F(n-1) + F(n-2) n
Everything is recursive … Linear search Length of a string Min, max of an array Selection sort Bubble sort … Binary search: Compare search element with middle element of the array: n If not equal, then apply binary search to half of the array (if not empty) where the search element would be. n
For n elements in an array: Start from the first element while (not yet finished) do the current element move to the next one do-something(n) If 0 or 1 element, just do it else (decompose into first element and the n-1 remaining elements) do the first element do-something(n-1)
Sum of an array Write a recursive function that computes the sum of all elements in an array of integers. What is the summation of n elements? int summation(int a[], int size){ int sum; if(size==0) sum=0; else sum=summation(a, size-1)+a[size-1]; return sum; }
Product of an array Write a recursive function that computes the product of an array of integers. What is the product of n elements? int product(int a[], int size) { int prod; if(size==0) prod=1; else prod=product(a, size-1)*a[size-1]; return prod; }
Recursion general form How to write recursively? function-type function(parameters) { function-type value; if(stopping conditions) value = stopping value; else value = g(function((revised parameters))); return value; }
Exponential How to write exp(int x, int y) recursively? int exp(int x, int y) { int power; if(y==0) power = 1; else power = x * exp(x, y-1); return power; }
Counting the number of zeros * * Write a recursive function that counts the number of zero digits in a non-negative integer zeros(10200) returns 3 int zeros(int n){ int z; if (n<10) if (n==0) z=1; else z=0; else z=zeros(n/10)+zeros(n%10); } l l return z; n/10 the number n with the last digit removed n%10 the last digit of n
Find factors Write a recursive function to determine how many factors m are part of n. For example, if n=48 and m=4, then the result is 2 (48=4*4*3). int factors(int n, int m){ int f; if(n%m != 0) f=0; else f=1+factors(n/m, m); return f; }
Summary natural consequence of ‘top-down’ analysis * ‘everything’ is recursive * * Decomposition-composition * Let’s trace a few examples … zeros(123009840) n asum(A, 5) n exp(6, 4) n … n
A more subtle example: the max of an array max(n): start from the first element: max=the-first while (not yet finished) pick up new-element max=maximum. Of. Two(max, new-element) move to the next element if one-element, max = one-element else decompose n elements into: 1 -element and n-1 element m 1 = the 1 -element m 2 = max(n-1) compose the final solution: max = maximum. Of. Two(m 1, m 2) int max 2(int m 1, int max 2) {return (m 1>m 2)? m 1: m 2; }; int max(int A[], int n) { int max=A[0]; int i=1; while (i<n) { max=max 2(max, A[i]); i=i+1; } return max; } int max 2(int m 1, int max 2) {return (m 1>m 2)? m 1: m 2; }; int max(int A[], int size) { int max, m 2; if (size==1) max=A[size-1]; else m 2=max(A, size-1); max=max 2(A[size-1], m 2); return max; }
Efficiency int max 2(int m 1, int max 2) {return (m 1>m 2)? m 1: m 2; }; int max(int A[], int size) { int max; if (size==1) max=A[size-1]; else max=max 2(max(A, size-1), A[size-1]); return max; } int max(int A[], int size) { int max; if (size==1) max=A[size-1]; else if(max(A, size-1)>A[size-1])) max=max(A, size-1); else max=A[size-1]; return max; } int max(int A[], int size) { if (size==1) return A[size-1]; else if(max(A, size-1)>A[size-1])) return max(A, size-1); else return A[size-1]; } The same code, but no intermediate storage ‘m 2’, it will have more recursive calls … inefficient!
Fibonacci (quite inefficient) int fibonacci(int n) { int f; if(n==0) f=0; else if (n==1) f=1; else f= fibonacci(n-1)+fibonacci(n-2); return f; } How many calls?
(Iterative) Fibonacci int fibonacci(int n) { int fib; int fibm 1=1; int fibm 2=0; if(n==0) fib=0; else if (n==1) fib=1; int j; for(j=2; j<=n; j++) { fib=fibm 1+fibm 2; fibm 2=fibm 1; fibm 1=fib; } return fib; }
Linear search Input: an array of integers A, and a value Output: the position of the value in the array if one element, check it! else decompose into 1 -element and n-1 elements check the 1 -element search(n-1)
int search(int A[], int size, int value) { int pos; if (size==1) if(A[size-1]==value) pos=1; else pos=-1; else if(A(size-1]==value) pos=size-1; else pos=search(A, size-1, value); return pos; }
(Binary) Search in a sorted array Input: a sorted array of integers A, and a value Output: the position of the value in the array
Binary search Input: a sorted array of integers A, and a value Output: the position of the value in the array if the middle element == value, done! else if the middle element > value do the same in the first half of the array else do the same in the second half of the array }
int bsearch(int data[], lower, upper, value) { int pos; if (lower<=upper) { mid=(lower+upper)/ 2; if (data[mid] == value) pos=mid; else if (data[mid]>value) pos=bsearch(data, lower, mid– 1, value); else pos=bsearch(data, mid+1, upper, value); } } return pos;
(iterative) Binary search: int bsearch(int data[], int size, int value) { int lower, middle, upper; bool found; lower = 0; upper = size - 1; found=false; position=-1; while ((lower<=upper) && (!found)) { middle = (lower+upper)/2; if (data[middle] == value) { found=true; position=middle; } else { if (data[middle] > value) upper = middle - 1; else lower = middle + 1; } } } return position; int main() { const int size=8; int data[size] = {1, 5, 6, 7, 9, 10, 17, 30}; int value; cin >> value; cout << “position of the value is “ << bsearch(data, size, value) << endl; }
The tower of Hanoi! Move a stack of disks of different sizes from one rod to another through a third one: - only one disk is moved each time - always smaller ones on top of bigger ones Check any webpage!
// move n disks from A to C via B void tower(int n, char A, char B, char C) { if (n==1) move(1, A, C); else {tower(n-1, A, C, B); move(n, A, C); tower(n-1, B, A, C)}; } void move(int k, char X, char Y) { cout << “move disc ” << k << “ from “ << X << “ to “ Y “ << endl; }
trace tower(3, A, B, C) …
There are systematic ways of de-recursing a function l Hanoi tower is easy to write in recursive form, l but very hard to write in iterative from! l l. LISP l l (scheme) language (for AI, Fortran for computing): functional programming language intrinsically recursive (loops are rarely used)
For n elements in an array: Start from the first element While (not yet finished) do the current element move to the next one Do. Sth(n) If 0 or 1 element, just do it else decompose into first element and the n-1 remaining elements (trivially) do the first element Do. Sth(n-1) compose the solution of n elements
Palindrome in an array of integers or character of known size…
bool palindrom(int a[], lower, upper) { bool pal=false; if (lower>=upper) pal=true; else pal=(a[lower]==a[upper]) && palindrom(a, lower+1, upper-1); } return pal; int main() { … palindrom(a, 0, 10); … }