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.
29
Embed
Recursion A recursive function is a function that calls itself either directly or indirectly through another function. The problems that can be solved.
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
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.
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.
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.
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); }
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;
}
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; } } }
Tracing a Recursive Function• Multiply(6, 3)
m = 6, n = 11 == 1 is true
ans is 6return (ans)
m = 6, n = 22 == 1 is false
ans is 6 + multiply(6, 2)return (ans)
Three activation frames corresponding to each call of the function are generated to solve the problem.
m = 6, n = 33 == 1 is false
ans is 6 + multiply(6, 2)return (ans)
6
12
18
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);
}
}
Tracing a Void Recursive Function• Reverse_input_words (3)
n = 1 ** 1 <= 1 is truescan “you” into word
display “you”return
n = 2 ** 2 <= 1 is false scan “are” into word
reverse_input_words(1)display “are”
return
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
A void function’s returnoccurs when the closing brace of the function body is encountered.
** word is undefined
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.
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.
Example • 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
3 ?
3 How
23
?How
23
areHow
123
youareHow
123
?areHow
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.
123
youareHow
23
AreHow
3 How
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.
Recursive factorial Function // 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); }
!1 = 1 !4 = 4 * !3
= 4 * 3 * !2 = 4 * 3 * 2 * !1 = 4 * 3 * 2 * 1
= 24
Recursive fibonacci Function // 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); }
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.
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.
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.