1 RECURSION Data Structures And AlgorithmsCSC221 Spring 2016

  • Slides: 36
Download presentation
1 RECURSION Data Structures And Algorithms(CSC-221) - Spring 2016

1 RECURSION Data Structures And Algorithms(CSC-221) - Spring 2016

What will be discussed 2 Recursion v/s Iteration Data Structures And Algorithms(CSC-221) - Spring

What will be discussed 2 Recursion v/s Iteration Data Structures And Algorithms(CSC-221) - Spring 2016

Recursion 3 Recursive Definition – one that defines something in terms of itself Recursion

Recursion 3 Recursive Definition – one that defines something in terms of itself Recursion – A technique that allows us to break down a problem in to one or more subproblems that are similar in form to the original problem. Either the problem or the associated data can be recursive in nature 3 Data Structures And Algorithms(CSC-221) - Spring 2016

Iterative Factorial 4 Iterative definition N! = N * (N-1) * (N-2) * …

Iterative Factorial 4 Iterative definition N! = N * (N-1) * (N-2) * … * 3 * 2 * 1 int factorial (int n) { int i, result; result = 1; for (i = 1; i <= n; i++) { result = result * i; } return ( result ); } 4 Data Structures And Algorithms(CSC-221) - Spring 2016

Recursive Factorial 5 Recursive N! definition N! = 1 if N = 0 =

Recursive Factorial 5 Recursive N! definition N! = 1 if N = 0 = N * (N-1)! Otherwise int factorial ( int n) { if (n == 0) return (1); return (n * factorial(n - 1) ); } 5 Data Structures And Algorithms(CSC-221) - Spring 2016

6 Iterative vs Recursive factorial 6 Iterative 1. 2 local variables 2. 3 statements

6 Iterative vs Recursive factorial 6 Iterative 1. 2 local variables 2. 3 statements 3. Saves solution in an intermediate variable Recursive 1. No local variables 2. One statement 3. Returns result in single expression Recursion simplifies factorial by making the computer do the work. What work and how is it done? Data Structures And Algorithms(CSC-221) - Spring 2016

How does it work? 7 Each recursive call creates an “activation record” which contains

How does it work? 7 Each recursive call creates an “activation record” which contains local variables and parameters return address and is saved on the stack. 7 Data Structures And Algorithms(CSC-221) - Spring 2016

Recursive Power 9 Recursive definition XN = 1 if N = 0 = X

Recursive Power 9 Recursive definition XN = 1 if N = 0 = X * X(N-1) otherwise double power(double number, int exponent) // Precondition: exponent >= 0 { if (exponent == 0) return (1); return (number * power(number, exponent-1)); } 9 Data Structures And Algorithms(CSC-221) - Spring 2016

Iteratively Sum an Array 10 int Sum. Array (int a[ ], int size) {

Iteratively Sum an Array 10 int Sum. Array (int a[ ], int size) { int j, sum = 0; for ( j = 0; j < size; j++ ) sum += a[ j ]; return sum; } 10 Data Structures And Algorithms(CSC-221) - Spring 2016

Recursively Sum an Array 11 int Sum. Array ( int a [ ], int

Recursively Sum an Array 11 int Sum. Array ( int a [ ], int size) { if (size == 0) return 0; else return array[ size – 1] + Sum. Array (a, size – 1); } 11 Data Structures And Algorithms(CSC-221) - Spring 2016

Approach to Writing Recursive Functions 12 Using “factorial” as an example, 1. Write the

Approach to Writing Recursive Functions 12 Using “factorial” as an example, 1. Write the function header so that you are sure what the function will do and how it will be called. [For factorial, we want to send in the integer for which we want to compute the factorial. And we want to receive the integer result back. ] int factorial(int n) 12 Data Structures And Algorithms(CSC-221) - Spring 2016

Approach (cont’d) 13 2. Decompose the problem into subproblems (if necessary). For factorial, we

Approach (cont’d) 13 2. Decompose the problem into subproblems (if necessary). For factorial, we must compute (n-1)! 3. Write recursive calls to solve those subproblems whose form is similar to that of the original problem. There is a recursive call to write: factorial(n-1) ; ] 13 Data Structures And Algorithms(CSC-221) - Spring 2016

Approach (cont’d) 14 4. Write code to combine, augment, or modify the results of

Approach (cont’d) 14 4. Write code to combine, augment, or modify the results of the recursive call(s) if necessary to construct the desired return value or create the desired side effects. When a factorial has been computed, the result must be multiplied by the current value of the number for which the factorial was taken: return (n * factorial(n-1)); 14 Data Structures And Algorithms(CSC-221) - Spring 2016

Approach (cont’d) 15 5. Write base case(s) to handle any situations that are not

Approach (cont’d) 15 5. Write base case(s) to handle any situations that are not handled properly by the recursive portion of the program. The base case for factorial is that if n=0, the factorial is 1: if (n == 0) return(1); 15 Data Structures And Algorithms(CSC-221) - Spring 2016

Ensuring that Recursion Works 16 Using “factorial” as an example, 1. A recursive subprogram

Ensuring that Recursion Works 16 Using “factorial” as an example, 1. A recursive subprogram must have at least one base case and one recursive case (it's OK to have more than one base case and/or more than one recursive case). The first condition is met, because if (n==0) return 1 is a base case, while the "else" part includes a recursive call (factorial(n-1)). 16 Data Structures And Algorithms(CSC-221) - Spring 2016

Does It Work? (cont’d) 17 2. The test for the base case must execute

Does It Work? (cont’d) 17 2. The test for the base case must execute before the recursive call. If we reach the recursive call, we must have already evaluated if (n==0); this is the base case test, so this criterion is met. 17 Data Structures And Algorithms(CSC-221) - Spring 2016

Does It Work? (cont’d) 18 3. The problem must be broken down in such

Does It Work? (cont’d) 18 3. The problem must be broken down in such a way that the recursive call is closer to the base case than the top-level call. The recursive call is factorial(n-1). The argument to the recursive call is one less than the argument to the top-level call to factorial. It is, therefore, “closer” to the base case of n=0. 18 Data Structures And Algorithms(CSC-221) - Spring 2016

Does It Work? (cont’d) 19 4. The recursive call must not skip over the

Does It Work? (cont’d) 19 4. The recursive call must not skip over the base case. Because n is an integer, and the recursive call reduces n by just one, it is not possible to skip over the base case. 19 Data Structures And Algorithms(CSC-221) - Spring 2016

Does It Work? (cont’d) 20 5. The non-recursive portions of the subprogram must operate

Does It Work? (cont’d) 20 5. The non-recursive portions of the subprogram must operate correctly. Assuming that the recursive call works properly, we must now verify that the rest of the code works properly. We can do this by comparing the code with our definition of factorial. This definition says that if n=0 then n! is one. Our function correctly returns 1 when n is 0. If n is not 0, the definition says that we should return (n-1)! * n. The recursive call (which we now assume to work properly) returns the value of n-1 factorial, which is then multiplied by n. Thus, the non--recursive portions of the function behave as required. 20 Data Structures And Algorithms(CSC-221) - Spring 2016

Recursion vs. Iteration 21 Recursion · Usually less code – algorithm can be easier

Recursion vs. Iteration 21 Recursion · Usually less code – algorithm can be easier to follow (Towers of Hanoi, binary tree traversals, flood fill) · Some mathematical and other algorithms are naturally recursive (factorial, summation, series expansions, recursive data structure algorithms) 21 Data Structures And Algorithms(CSC-221) - Spring 2016

Recursion vs. Iteration (cont’d) 22 Iteration · Use when the algorithms are easier to

Recursion vs. Iteration (cont’d) 22 Iteration · Use when the algorithms are easier to write, understand, and modify (especially for beginning programmers) · Generally, runs faster because there is no stack I/O · Sometimes are forced to use iteration because stack cannot handle enough activation records (power(2, 5000)) 22 Data Structures And Algorithms(CSC-221) - Spring 2016

Direct Recursion 23 A C function is directly recursive if it contains an explicit

Direct Recursion 23 A C function is directly recursive if it contains an explicit call to itself Int foo (int x) { if ( x <= 0 ) return x; return foo ( x – 1); } 23 Data Structures And Algorithms(CSC-221) - Spring 2016

Indirect Recursion 24 A C function foo is indirectly recursive if it contains a

Indirect Recursion 24 A C function foo is indirectly recursive if it contains a call to another function that ultimately calls foo. int bar (int y) int foo (int x){ if (x <= 0) return x; { return foo (y – 1); return bar(x); } } 24 Data Structures And Algorithms(CSC-221) - Spring 2016

Tail Recursion 25 A recursive function is said to be tail recursive if there

Tail Recursion 25 A recursive function is said to be tail recursive if there is no pending operations performed on return from a recursive call Tail recursive functions are often said to “return the value of the last recursive call as the value of the function” 25 Data Structures And Algorithms(CSC-221) - Spring 2016

factorial is non-tail recursive 26 int factorial (int n) { if (n == 0)

factorial is non-tail recursive 26 int factorial (int n) { if (n == 0) return 1; return n * factorial(n – 1); } Note the “pending operation” (namely the multiplication) to be performed on return from each recursive call 26 Data Structures And Algorithms(CSC-221) - Spring 2016

Tail recursive factorial 27 int fact_aux (int n, int result) { if (n ==

Tail recursive factorial 27 int fact_aux (int n, int result) { if (n == 1) return result; return fact_aux (n – 1, n * result); } factorial (int n) { return fact_aux (n, 1); } 27 Data Structures And Algorithms(CSC-221) - Spring 2016

Linear Recursion 28 A recursive function is said to be linearly recursive when no

Linear Recursion 28 A recursive function is said to be linearly recursive when no pending operation invokes another recursive call to the function. int factorial (int n) { if (n == 0) return 1; return n * factorial ( n – 1); } 28 Data Structures And Algorithms(CSC-221) - Spring 2016

Linear Recursive Count_42 s 29 int count_42 s(int array[ ], int n) { if

Linear Recursive Count_42 s 29 int count_42 s(int array[ ], int n) { if (n == 0) return 0; if (array[ n-1 ] != 42) { return (count_42 s( array, n-1 ) ); } return (1 + count_42 s( array, n-1) ); } 29 Data Structures And Algorithms(CSC-221) - Spring 2016

Tree Recursion 30 A recursive function is said to be tree recursive (or non-linearly

Tree Recursion 30 A recursive function is said to be tree recursive (or non-linearly recursive when the pending operation does invoke another recursive call to the function. The Fibonacci function fib provides a classic example of tree recursion. 30 Data Structures And Algorithms(CSC-221) - Spring 2016

Fibonacci Numbers 31 The Fibonacci numbers can be recursively defined by the rule: fib(n)

Fibonacci Numbers 31 The Fibonacci numbers can be recursively defined by the rule: fib(n) = 0 if n is 0, = 1 if n is 1, = fib(n-1) + fib(n-2) otherwise For example, the first seven Fibonacci numbers are Fib(0) = 0 Fib(1) = 1 Fib(2) = Fib(1) + Fib(0) = 1 Fib(3) = Fib(2) + Fib(1) = 2 Fib(4) = Fib(3) + Fib(2) = 3 Fib(5) = Fib(4) + Fib(3) = 5 Fib(6) = Fib(5) + Fib(4) = 8 31 Data Structures And Algorithms(CSC-221) - Spring 2016

Tree Recursive Fibonacci 32 // Note how the pending operation (the +) // needs

Tree Recursive Fibonacci 32 // Note how the pending operation (the +) // needs a 2 nd recursive call to fib int fib(int n) { if (n == 0) return 0; if (n == 1) return 1; return ( fib ( n – 1 ) + fib ( n – 2 ) ); } 32 Data Structures And Algorithms(CSC-221) - Spring 2016

Tree Recursive Count_42 s 33 int count_42 s(int array[ ], int low, int high)

Tree Recursive Count_42 s 33 int count_42 s(int array[ ], int low, int high) { if ((low > high) || (low == high && array[low] != 42)) { return 0 ; } if (low == high && array[low] == 42) { return 1; } return (count_42 s(array, low, (low + high)/2) + count_42 s(array, 1 + (low + high)/2, high)) ); } 33 Data Structures And Algorithms(CSC-221) - Spring 2016

34 Converting Recursive Functions to Tail Recursion A non-tail recursive function can often be

34 Converting Recursive Functions to Tail Recursion A non-tail recursive function can often be converted to a tail recursive function by means of an “auxiliary” parameter that is used to form the result. The idea is to incorporate the pending operation into the auxiliary parameter in such a way that the recursive call no longer has a pending operations (is tail recursive) 34 Data Structures And Algorithms(CSC-221) - Spring 2016

Tail Recursive Fibonacci 35 int fib_aux ( int n, int next, int result )

Tail Recursive Fibonacci 35 int fib_aux ( int n, int next, int result ) { if ( n == 0 ) return result; return ( fib_aux ( n - 1, next + result, next )); } int fib ( int n ) { return fib_aux ( n, 1, 0 ); } 35 Data Structures And Algorithms(CSC-221) - Spring 2016

An exercise for the Student 36 Convert the following for loop that finds the

An exercise for the Student 36 Convert the following for loop that finds the maximum value in an array to be tail recursive. Assume that the function max( ) returns the larger of the two parameters returned to it. int nums[MAX]; // filled by some other function int max_num = nums[ 0 ]; for (j = 0; j < MAX; j++) max_num = max (max_num, nums[ j ] ); 36 Data Structures And Algorithms(CSC-221) - Spring 2016

Conclusion 37 In this Lecture we discussed… • What is Recursion? ANY QUERY ?

Conclusion 37 In this Lecture we discussed… • What is Recursion? ANY QUERY ? Data Structures And Algorithms(CSC-221) - Spring 2016