Sudeshna Sarkar, IIT Kharagpur 1 Functions : Recursion Lecture
Sudeshna Sarkar, IIT Kharagpur 2 Announcements Class Test – I on 7 th February, 6pm Section 1 & 2 at S-301 Section 5 & 6 at S-302
Sudeshna Sarkar, IIT Kharagpur 3 Call by value void printDouble (int x) { printf (“Double of %d “, x); x *= 2; printf (“is %d\n”, x) ; } void main () { int num=15; printDouble (num); printf (“ num = %d\n”, num); } Note : The parameter of a function can be a constant, variable, expression – anything that has a value. Only the value is passed to the function.
Sudeshna Sarkar, IIT Kharagpur 4 Recursion Def : A function is recursive if it calls itself. int rfun (int x) {... rfun (2*a) ;... } Questions : How does recursion work ? Why do I write a recursive function ?
Sudeshna Sarkar, IIT Kharagpur 5 Thinking Recursively Learning Objectives To learn to think recursively To learn how strategies for recursion involve both base cases and recursion cases To learn how to search for different ways of decomposing a problem into subproblems. To understand how to use call trees and traces to reason about how recursive programs work
Sudeshna Sarkar, IIT Kharagpur 6 Program vs Process Program = a set of instructions akin to the blueprint of an information factory Process = activity performed by computer when obeying the instructions akin to operation of a working factory can create multiple factories as needed from the same blueprint need to allocate different local variables
Sudeshna Sarkar, IIT Kharagpur 7 Factorial via Recursion /* 0! = 1! = 1, for n>1, n! = n* (n-1)! */ int factorial (int n) { int t; if (n <=1) t=1; else t = n * factorial (n-1) ; return t; }
Sudeshna Sarkar, IIT Kharagpur 8 Review : Function Basics Tracing recursive functions is apparent if you remember the basics about functions : Formal parameters and variables declared in a function is local to it. Allocated (created) on function entry De-allocated (destroyed) on function return Formal parameters initialized by copying value of actual parameter.
Sudeshna Sarkar, IIT Kharagpur 9 Factorial factorial (4) = 4 * factorial (3) = 4 * 3 * factorial (2) = 4 * 3 * 2 * factorial (1) = 4 * 3 * 2 * 1 = 24
Sudeshna Sarkar, IIT Kharagpur 10 Factorial Trace n t n t n t n t n t
Sudeshna Sarkar, IIT Kharagpur 11 int findmax (int n) { int i, num, max; scanf ("%d", &num) ; max = num; for (i=1; i<n; i++){ scanf ("%d", &num) ; if (num > max) max = num; } return max; } int findmax (int n, int max) { int num; if (n==0) return max; scanf ("%d", &num) ; if (num > max) max = num; max = findmax (n-1, max) ; return max; }
Sudeshna Sarkar, IIT Kharagpur 12 Iteration vs. Recursion Any iterative algorithm can be re-worked to use recursion, and vice-versa. Some algorithms are more naturally written with recursion. But naive applications of recursion can be inefficient.
Sudeshna Sarkar, IIT Kharagpur 13 When to use Recursion ? Problem has 1 or more simple cases. These have a straightforward non-recursive solution. Other cases can be re-defined in terms of problems that are closer to simple cases By applying this redefn process repeatedly one gets to one of the simple cases.
Sudeshna Sarkar, IIT Kharagpur 14 Example int sumSquares (int m, int n) { int i, sum; sum = 0; for (i=m; i<=n; i++) sum += i*i; return sum; }
Sudeshna Sarkar, IIT Kharagpur 15 Example int sumSquares (int m, int n) { if (m<n) /* Recursion */ return sumSquares(m, n-1) + n*n; else /* Base Case */ return n*n ; } int sumSquares (int m, int n) { if (m<n) /* Recursion */ return m*m + sumSquares(m+1, n); else /* Base Case */ return m*m ; }
Sudeshna Sarkar, IIT Kharagpur 16 Example int sumSquares (int m, int n) { int middle ; if (m==n) return m*m; else { middle = (m+n)/2; return sumSquares(m,middle) + sumSquares(middle+ 1,n) ; } m midmid+1 n
Sudeshna Sarkar, IIT Kharagpur 17 Call Tree sumSquares(5,10) sumSquares(5,7) sumSquares(5,10)sumSquares(8,10) sumSquares(5,6) sumSquares(7,7) sumSquares(8,9) sumSquares(10,10) sumSquares(5,5) sumSquares(6,6)sumSquares(8,8) sumSquares(9,9)
Sudeshna Sarkar, IIT Kharagpur 18 Annotated Call Tree sumSquares(5,10) sumSquares(5,7) sumSquares(5,10)sumSquares(8,10) sumSquares(5,6) sumSquares(7,7) sumSquares(8,9) sumSquares(10,10) sumSquares(5,5) sumSquares(6,6)sumSquares(8,8) sumSquares(9,9)
Sudeshna Sarkar, IIT Kharagpur 19 Trace sumSq(5,10) = (sumSq(5,7) + sumSq(8,10)) = (sumSq(5,6) + (sumSq(7,7)) + (sumSq(8,9) + sumSq(10,10)) = ((sumSq(5,5) + sumSq(6,6)) + sumSq(7,7)) + ((sumSq(8,8) + sumSq(9,9)) + sumSq(10,10)) = (( ) + 49) + (( ) + 100) = ( ) + ( ) = ( ) = 355
Sudeshna Sarkar, IIT Kharagpur 20 Recursion : The general idea Recursive programs are programs that call themselves to compute the solution to a subproblem having these properties : 1. the subproblem is smaller than the overall problem or, simpler in the sense that it is closer to the final solution 2. the subproblem can be solved directly (as a base case) or recursively by making a recursive call. 3. the subproblem’s solution can be combined with solutions to other subproblems to obtain the solution to the overall problem.
Sudeshna Sarkar, IIT Kharagpur 21 Think recursively Break a big problem into smaller subproblems of the same kind, that can be combined back into the overall solution : Divide and Conquer
Sudeshna Sarkar, IIT Kharagpur 22 Exercise 1. Write a recursive function that computes x n, called power (x, n), where x is a floating point number and n is a non- negative integer. 2. Write an improved recursive version of power(x,n) that works by breaking n down into halves, squaring power(x, n/2), and multiplying by x again if n is odd. 3. To calculate the square root of x (a +ve real) by Newton’s method, we start with an initial approximation a=x/2. If |x- a a| epsilon, we stop with the result a. Otherwise a is replaced with the next approximation, (a+x/a)/2. Write a recursive method, sqrt(x) to compute square root of x by Newton’s method.
Sudeshna Sarkar, IIT Kharagpur 23 Common Pitfalls Infinite Regress : a base case is never encountered a base case that never gets called : fact (0) running out of resources : each time a function is called, some space is allocated to store the activation record. With too many nested calls, there may be a problem of space. int fact (int n) { if (n==1) return 1; return n*fact(n-1); }
Sudeshna Sarkar, IIT Kharagpur 24 Tower of Hanoi ABC
Sudeshna Sarkar, IIT Kharagpur 25 Tower of Hanoi ABC
Sudeshna Sarkar, IIT Kharagpur 26 Tower of Hanoi ABC
Sudeshna Sarkar, IIT Kharagpur 27 Tower of Hanoi ABC
Sudeshna Sarkar, IIT Kharagpur 28 void towers (int n, char from, char to, char aux) { if (n==1) { printf (“Disk 1 : %c -> &c \n”, from, to) ; return ; } towers (n-1, from, aux, to) ; printf (“Disk %d : %c %c\n”, n, from, to) ; towers (n-1, aux, to, from) ; }
Sudeshna Sarkar, IIT Kharagpur 29 Disk 1 : A -> C Disk 2 : A -> B Disk 1 : C -> B Disk 3 : A -> C Disk 1 : B -> A Disk 2 : B -> C Disk 1 : A -> C Disk 4 : A -> B Disk 1 : C -> B Disk 2 : C -> A Disk 1 : B -> A Disk 3 : C -> B Disk 1 : A -> C Disk 2 : A -> B Disk 1 : C -> B towers (4, ‘A’, ‘B’, ‘C’) ;
Sudeshna Sarkar, IIT Kharagpur 30 Recursion may be expensive ! Fibonacci Sequence: fib (n) = n if n is 0 or 1 fib (n) = fib (n-2) + fib(n-1) if n>= 2. int fib (int n){ if (n==0 or n==1) return 1; return fib(n-2) + fib(n-1) ; }
Sudeshna Sarkar, IIT Kharagpur 31 Call Tree fib (5) fib (3)fib (4) fib (1) fib (2)fib (1)fib (2) fib (0) fib (3) fib (1) fib (2) fib (0) fib (1)
Sudeshna Sarkar, IIT Kharagpur 32 Iterative fibonacci computation int fib (int n){ if (n <= 1) return n; lofib = 0 ; hifib = 1 ; for (i=2; i<=n; i++) { x = lofib ; lofib = hifib ; hifib = x + lofib; } return hifib ; } i = x = lofib= hifib=
Sudeshna Sarkar, IIT Kharagpur 33 Merge Sort To sort an array of N elements, 1. Divide the array into two halves. Sort each half. 2. Combine the two sorted subarrays into a single sorted array Base Case ?
Sudeshna Sarkar, IIT Kharagpur 34 Binary Search revisited To search if key occurs in an array A (size N) sorted in ascending order: mid = N/2; if (key == N/2) item has been found if (key < N/2) search for the key in A[0..mid-1] if (key > N/2) search for key in A[mid+1..N] Base Case ?