Topic 6 Recursion Objectives You should be able
Topic 6 Recursion
Objectives You should be able to: n n n Mentally execute recursive functions Write and understand programs which contain recursive functions Convert a while loop into a call to a recursive function Program Development and Design Using C++, Third Edition 2
Recursion (Chapter 6 in textbook-section 6. 6) n A function that is defined in terms of itself is called recursive e. g. 0 if x=0 2 f(x-1) + x 2 if x>0 f(x)= Program Development and Design Using C++, Third Edition 3
Example of fun() 2*fun(2)+3*3 int fun(int x) { if (x==0) return 0; else return 2*fun(x-1)+x*x; } 2*(2*fun(1)+2*2)+3*3 2*(2*(2*fun(0)+1*1)+2*2)+3*3 Recursive call for fun(3): 0 =2*(2*(2*0+1)+4)+9 Returned value of fun(3): 21 Program Development and Design Using C++, Third Edition 4
Recursion n Recursive functions q q n Functions that call themselves Can only solve a base case If not base case q q Break problem into smaller problem(s) Launch new copy of function to work on the smaller problem (recursive call/recursive step) n n q Slowly converges towards base case Function makes call to itself inside the return statement Eventually base case gets solved n Answer works way back up, solves entire problem Program Development and Design Using C++, Third Edition 5
Recursion: How the Computation Is Performed n C++ allocates new memory locations for function parameters and local variables as each function is called q q Allocation made dynamically in memory stack Memory stack: Area of memory used for rapidly storing and retrieving data n Last-in/first-out Program Development and Design Using C++, Third Edition 6
Rules of Recursion Two fundamental rules of recursion: n n Base cases. You must always have some base cases which can be solved without recursion. Making Progress. For the cases that are to be solved recursively, the recursive call must always be to a case that makes progress toward a base case. Program Development and Design Using C++, Third Edition 7
An incorrect recursive function int sum(int n) { return n+sum(n-1); } This function does not have a base case Program Development and Design Using C++, Third Edition 8
A correct recursive function int sum(int n) { if (n==0) return 0; else return n+sum(n-1); } void main() { cout<<sum(3); } Program Development and Design Using C++, Third Edition 9
How the computation is performed: The stack int sum(int n) { if (n==0) return 0; else return n+sum(n-1); } void main() { cout<<sum(3); } sum(0) n=0 0 sum(1) n=1 1+0=1 sum(2) n=2 2+1=3 sum(3) n=3 main() 3+3=6 Output: 6 Program Development and Design Using C++, Third Edition 10
A non-terminating recursive program int Bad(int n) { if (n==0) return 0; else return Bad(n/3+1)+n-1; } Program Development and Design Using C++, Third Edition 11
Factorial example n factorial n! = n * ( n – 1 ) * ( n – 2 ) * … * 1 q Recursive relationship ( n! = n * ( n – 1 )! ) 5! = 5 * 4! 4! = 4 * 3!… q Base case (1! = 0! = 1) Program Development and Design Using C++, Third Edition 12
Recursive factorial function int factorial(int n) { if ( n==0 ) // base case return 1; else // recursive step return n*factorial(n - 1); } Program Development and Design Using C++, Third Edition 13
Testing the factorial function void main() { int i; // Loop 5 times. During each iteration, calculate // factorial( i ) and display result. for ( i = 0; i <= 5; i++ ) cout << i << "! = "<< factorial( i ) << endl; } Output: 0! = 1 1! = 1 2! = 2 3! = 6 4! = 24 5! = 120 Program Development and Design Using C++, Third Edition 14
Drawing a triangle recursively void Triangle(int n) { //draws a right-angled triangle if (n!=0) { line(n, '*'); //function Line cout<<endl; Triangle(n-1); } } from previous chapter Program Development and Design Using C++, Third Edition 15
Testing the function Triangle #include <iostream> using namespace std; void line(int x, char ch) ; void Triangle(int n); void line(int x, char ch) { int i; for(i=1; i<=x; i++) cout << ch ; } //function prototypes //function definitions void Triangle(int n) { if (n!=0) { line(n, '*'); cout<<endl; Triangle(n-1); } } Program Development and Design Using C++, Third Edition 16
Testing the function Triangle(ctd) void main() { int x; cout<<"Please enter the height of the triangle: "; cin>>x; while (x<=0) { cout<<"Please enter a positive height of the triangle: "; cin>>x; } Triangle(x); } Program Development and Design Using C++, Third Edition 17
The connection between recursion and looping n We can always re-write a while loop as a recursive function: while (<expression>) <statement> //This n is any sequence of statements in curly brackets This while loop can be replaced by a call to the recursive function f: void f() { if (<expression>) { <statement>; f(); } } Program Development and Design Using C++, Third Edition 18
A non-recursive Triangle function void Triangle(int n) { while (n!=0) { line(n, '*'); cout<<endl; n--; } } Program Development and Design Using C++, Third Edition 19
Example Using Recursion: Fibonacci Sequence (exercises 6. 6, pg. 355, ex. 1) n Fibonacci sequence: 0, 1, 1, 2, 3, 5, 8. . . q n n Each number sum of two previous ones (except for the first two numbers). Write a recursive function that returns the nth number in the Fibonacci sequence, when n is passed to the function as argument. For example: when n=8, the function should return the eighth number in the sequence, which is 21 (starting from 0). Program Development and Design Using C++, Third Edition 20
The recursive Fibonacci function long fibonacci( long n ) { if ( n == 0 || n == 1 ) // base case return n; else return fibonacci( n - 1 ) + fibonacci( n – 2 ); } Program Development and Design Using C++, Third Edition 21
The recursive Fibonacci function f( 3 ) return f( 1 ) return 1 f( 2 ) + f( 0 ) + f( 1 ) return 1 return 0 Program Development and Design Using C++, Third Edition 22
What does this function do? void Rev() { int i; cin>>i; if (i!=-1) { Rev(); cout<<i<<endl; } } Program Development and Design Using C++, Third Edition 23
Answer: n n Reads a sequence of integers, terminated by -1 and outputs them in reverse order (excluding the -1). Example run: User enters: 2 5 7 8 -1 Output: 8 7 5 2 Program Development and Design Using C++, Third Edition 24
How to think recursively? n n n Recursive functions are implemented using an if-else (or switch) statement that leads to different cases. Break the problem into subproblems. Every recursive call reduces the original problem by bringing it closer and closer to the base case until it becomes that case. Identify the base case. This is the simplest case (could be more than one base cases) that will be used to stop recursion. Program Development and Design Using C++, Third Edition 25
Example of thinking recursively: Palindrome problem n n Considering writing a recursive palindrome function. A string is a palindrome if it reads the same from the left and from the right. This problem can be divided into two subproblems: q Check whether the first and last characters of the string are equal. q Ignore these two characters and check whether the rest of the substring is a palindrome. (The second problem is the same as the original problem with a smaller size). There are two base cases: 1. The two end characters are not the same, in which case the string not a palindrome 2. The string size is 0 or 1, in which case the string is a palindrome Program Development and Design Using C++, Third Edition 26
Recursive palindrome function n Classroom/lab exercise…. Program Development and Design Using C++, Third Edition 27
Exercises: 1. The recursive solution to the problem of finding the Fibonacci number we gave earlier, is very inefficient (why? ). Write a non-recursive Fibonacci function. Program Development and Design Using C++, Third Edition 28
Exercises (continued): 2. The greatest common divisor (gcd) of two integers p and q is the largest integer that divides both (e. g. gcd of 18 and 12 is 6). An algorithm to compute the greatest common divisor of two integers p and q is the following: Let r be the remainder of p divided by q. If r is 0, then q is the greatest common divisor. Otherwise, set p equal to q, then q equal to r, and repeat the process. Write a recursive function that implements the above algorithm. Program Development and Design Using C++, Third Edition 29
Exercises (continued): 3. Write a recursive function called locate that takes a string str, a character ch and an integer i and returns the index position of the first occurrence of character ch in string str. (The function assumes that there is an occurrence of the character at or after the index i in the string str). Example: cout<<locate("hello", 'l', 0); should print 2. Program Development and Design Using C++, Third Edition 30
- Slides: 30