1 / 29

Recursion

Recursion. A recursive function is a function that calls itself either directly or indirectly through another function. The problems that can be solved by recursion must have the following characteristics:

sporcaro
Download Presentation

Recursion

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Recursion • A recursive function is a function that calls itself either directly or indirectly through another function. • The problems that can be solved by recursion must have the following characteristics: • - One or more simple cases of the problem have a straightforward, nonrecursive solution. • - The other cases can be redefined in terms of problems that are closer to the simple cases. • - By applying this redefinition process every time the recursive function is called, eventually the problem is reduced entirely to simple cases, which are relatively easy to solve.

  2. Recursion • Recursive algorithm: • if this is a simple case • solve it • else • redefine the problem using recursion • Problem: Multiply 6 by 3. • The problem can be split into two problems: • - 1. Multiply 6 by 2. • - 2. Add 6 to the result of problem 1. • Now we can solve problem 2 because we know our addition tables. • But we cannot solve problem 1. Problem 1 is closer to the simple case than the original problem was. • The recursive approach splits one size-n problem into n size-1 problems.

  3. Recursion • Problem: Multiply 6 by 3. • The problem can be split into two problems: • - 1. Multiply 6 by 2. • - 2. Add 6 to the result of problem 1. • We can split problem 1 into two problems: • - 1.1 Multiply 6 by 1 • - 1.2 Add 6 to the result of problem 1.1 • Problem 1.1 is the simple case. We can solve it because we know that any number multiplied by 1 gives us the original number. • Here, we assumed that we know our addition tables. We can solve problem 1.2. • So, problem1 is solved. • We have already solved Problem 2. • Therefore, we have solved the problem.

  4. Recursive function multiply • // Performs integer multiplication using + operator. • // Pre: m and n are defined and n > 0 • int multiply ( int m, int n ) • { • int ans; • if (n == 1) • ans = m; // simple case • else • ans = m + multiply ( m, n -1 ); // recursive step • return (ans); • }

  5. Count the # of vowels in a string • #include <stdio.h> • #include < string.h> • int count_vowel (char *input); • int main() • { • char line[] = “Hello”; • int num, count; • printf(“num of vowels are %d\n”, count_vowels(line); • return 0; • }

  6. Count the # of vowels in a string • int count_vowels (char *string_ptr) • { • if (*str_ptr == ‘\0’) return 0; // simple case • else • { • switch (*string_ptr) • { // redefine problem using recursion • case ‘a’ : case ‘e’ : case ‘i’ : case ‘o’ : case ‘u’: • return (1 + count_vowels ( string_ptr + 1)); • break; • default : return count_vowels (string_ptr + 1); • break; • } • } • }

  7. Tracing a Recursive Function Three activation frames corresponding to each call of the function are generated to solve the problem. m = 6, n = 3 3 == 1 is false ans is 6 + multiply(6, 2) return (ans) 18 • Multiply(6, 3) m = 6, n = 2 2 == 1 is false ans is 6 + multiply(6, 2) return (ans) 12 m = 6, n = 1 1 == 1 is true ans is 6 return (ans) 6

  8. Function reverse_input_words • void reverse_input_words(int n) • { • char word[WORDSIZ]; • if (n <= 1) // simple case • { • scanf(“%s”, word); • printf(“%s\n”, word); • } • else // get and print the rest of the words • { // in reverse order and print it. • scanf(“%s”, word); • reverse_input_words(n - 1); • printf(“%s\n”, word); • } • }

  9. Tracing a Void Recursive Function Three activation frames corresponding to each call of the function are generated to solve the problem. n = 3 ** 3 <= 1 is false scan “how” into word reverse_input_words(2) display “how” return • Reverse_input_words (3) A void function’s return occurs when the closing brace of the function body is encountered. n = 2 ** 2 <= 1 is false scan “are” into word reverse_input_words(1) display “are” return n = 1 ** 1 <= 1 is true scan “you” into word display “you” return ** word is undefined

  10. Sequence of Events for the Function • Call reverse_input_words with n = 3. • Scan the first word (“How”) into word. • Call reverse_input_words with n = 2. • Scan the second word (“are”) into word. • Call reverse_input_words with n = 1. • Scan the third word (“you”) into word. • Display the third word (”you”). • Return from third call. • Display the second word (“are”). • Return from second call. • Display the first word (“How”). • Return from the original call.

  11. Parameter and Local Variable Stack • C uses the stack data structure to keep track of the values of n and word at any given point. • In this structure, we add data items and remove them from the same end of the list. • The last item stored is the first processed. • When executes a call to the function, the system pushes the parameter value on the top of the parameter stack. • Pushes a new undefined cell on top of the stack maintained for the local variable word. • A return from the function pops each stack, removing the top value.

  12. ? 3 3 1 2 3 1 2 3 you are How ? are How Example How • After first call to reverse_input_words • The word “How” is stored in word just before the second call • After the second call. • The word “are” is scanned and stored in word just before the third call • After the third call 2 3 ? How are How 2 3

  13. 1 2 3 you are How Example • During the execution of the function, the word “you” is scanned and stored in word, and “you”is printed immediately because • n =1 • The function return pops both stacks. After the first return: • After the second return • The third and last return exits the original function call. So there is no longer memory allocated for n and word. 2 3 Are How How 3

  14. System Stack • We have used separate stacks for each parameter in the example. • The compiler actually maintains a single system stack • Whenever a call to a function occurs, all its parameters and local variables are pushed onto the stack along with the memory address of the calling statement. • This address gives the computer the return point after execution of the function. • Multiple copies of a function’s parameters may be saved on the stack, only one copy of the function body is in memory.

  15. Recursive factorial Function !1 = 1 !4 = 4 * !3 = 4 * 3 * !2 = 4 * 3 * 2 * !1 = 4 * 3 * 2 * 1 = 24 • // Compute n! using recursion • // Pre: n >= 0 • int factorial (int n) • { • int ans; • if (n == 0) // simple case • ans = 1; • else // redefine problem using recursion • ans = n * factorial (n - 1); • return (ans); • }

  16. Recursive fibonacci Function Fibonacci sequence: 1, 1, 2, 3, 5, 8, 13, 21, 34, …. • // Compute the nth Fibonacci number using recursion • // Pre: n >= 0 • int fibonacci (int n) • { • int ans; • if (n == 1 || n == 2) // simple case • ans = 1; • else // redefine problem using recursion • ans = fibonacci(n - 2) + fibonacci (n - 1); • return (ans); • }

  17. Towers of Hanoi • Towers of Hanoi problem involves moving a specified number of disks that are all different sizes from one tower (or peg) to another. • Problem: Move n disks from peg A to peg C using peg B as an intermediate peg. • Conditions: • 1. Only one disk at a time may be moved, and this disk must be the top disk on a peg. • 2. A larger disk cannot be placed on top of a smaller disk.

  18. Tower of Hanoi Start 1 2 3 (B) (C) (A) Goal (A) (B) (C)

  19. Tower of Hanoi 1 (B) (C) (A) Simple case: single disk. Just move the disk 1 from peg A to peg C

  20. Tower of Hanoi Top (n - 1) disks 1 2 3 (B) (C) (A) Move the top (n -1) disks from peg A to peg B. (C) (A) (B)

  21. Tower of Hanoi 1 (A) (B) (C) Move the bottom disk (1) from peg A to peg C. (C) (A) (B)

  22. Tower of Hanoi Top (n - 1) disks (A) (B) (C) Move the top (n - 1) disks from peg B to peg C. (C) (A) (B)

  23. Data Requirements • Problem Inputs: • int n • char from_peg • char to_peg • char aux_peg • Problem Outputs: • A list of instructions for moving n disks from from_peg to to_peg using aux_peg as an intermediate peg.

  24. Algorithm • 1. if n is 1 then • 2. Move disk 1 from the from_peg to the to_peg. • else • 3. Move n - 1 disks from the from_peg to the auxiliary peg using the to_peg. • 4. Move disk n from the from_peg to the to_peg. • 5. Move n - 1 disks from the auxiliary peg to the to_peg using the from_peg.

  25. Recursive Function Tower • // Displays instruction for moving n disks from from_peg to to_peg // using aux_peg as an intermediate peg. • void tower ( char from_peg, char to_peg, char aux_peg, int n) • { • if (n == 1) // simple case • printf(“Move disk 1 from peg %c to peg %c\n”, • from_peg, to_peg); • else // redefine the problem using recursion • { • tower(from_peg, aux_peg, to_peg, n -1); • printf(“Move disk %d from peg %c to peg %c\n”, • n, from_peg, to_peg); • tower(aux_peg, to_peg, from_peg, n - 1); • } • }

  26. Output of tower Function • Output generated by tower (‘A’, ‘C’, ‘B’, 3): • Move disk 1 from A to C • Move disk 2 from A to B • Move disk 1 from C to B • Move disk 3 from A to C • Move disk 1 from B to A • Move disk 2 from B to C • Move disk 1 from A to C • n - disk problem requires 2n - 1 moves.

  27. Recursion Vs. Iteration • Both iteration and recursion are based on a control structure: iteration uses a repetition structure and recursion uses a selection structure. • Both iteration and recursion involve repetition. Iteration explicitly uses a repetition structure and recursion achieves repetition through repeated function calls. • Iteration and recursion each involve a termination test. Iteration terminates when the loop-continuation condition fails. Recursion terminates when the base case is reached. • Both iteration and recursion can occur infinitely.An infinite loop can occurs with iteration if the loop-continuation test never becomes false. Infinite recursion occurs if the recursive step does not reduce the problem each time in a manner that converges on the base case.

  28. Recursion Vs. Iteration • Recursion has many negatives. It repeatedly invokes the mechanism, and consequently the overhead, of function calls.This can be expensive in both processor time and memory space.. • Each recursive call causes another copy of the function (actually only the function’s variables) to be created. This can consume considerable memory. • Iteration normally occurs within a function so the overhead of repeated function calls and extra memory assignment is omitted. • So why choose recursion? • In many instances, the use of recursion enables us to specify a very natural, simple solution to a problem that would otherwise be very difficult to solve (e.g. Tower of Hanoi). • For this reason, recursion is an important and powerful tool in problem solving and programming.

More Related