Introduction to Recursion - digital.cs.usu.edudigital.cs.usu.edu/~allan/CS2/Slides/Recursion.pdfDt i...
Transcript of Introduction to Recursion - digital.cs.usu.edudigital.cs.usu.edu/~allan/CS2/Slides/Recursion.pdfDt i...
1
Chapter 19
Recursion
Introduction to Recursion
CS 1410 - SJAllan Chapter 19 2
2
Introduction to Recursion
CS 1410 - SJAllan Chapter 19 3
Introduction to Recursion
CS 1410 - SJAllan Chapter 19 4
3
Examples of Recursion
http://ejad.best.vwh.net/java/fractals/sierpinski.shtmlhttp://agutie.homestead.com/files/machupicchu sierpinski1.htmlp g p _ p
CS 1410 - SJAllan Chapter 19 5
Introduction to Recursion
CS 1410 - SJAllan Chapter 19 6
4
Definition
Recursion is solving a problem using recursionrecursion
http://www.mantasoft.co.uk/anim/show.php?url=Recursive.swf
CS 1410 - SJAllan Chapter 19 7
Another Definition of Recursion
A technique that solves a problem by solving a simpler sub problem of the same typea simpler sub-problem of the same type
CS 1410 - SJAllan Chapter 19 8
5
Defining Ancestors
Who is your ancestor?Y t tYour parents are your ancestors The parents of any ancestor are also your ancestors
CS 1410 - SJAllan Chapter 19 9
Rabbits Everywhere
In 1202, Fibonacci proposed a problem:Suppose that you have a pair of rabbitsEvery month the rabbits breed and have a pair of offspring who will begin the breeding process themselves in two monthsH i f bbit ill h i th
CS 1410 - SJAllan Chapter 19 10
How many pairs of rabbits will you have in month 1, 2, 3, 4, …, n?
6
Fibonacci
Month 1 = 1 Pair 1 New Born (NB)Month 1 = 1 Pair 1 New Born (NB)Month 2 = 1 Pair 1 Ready to Breed (RTB)Month 3 = 2 Pairs 1 Breeding (B) + 1 NBMonth 4 = 3 Pairs 1 B, 1 RTB, 1 NBMonth 5 = 5 Pairs 2 B 1 RTB 2 NB
CS 1410 - SJAllan Chapter 19 11
Month 5 = 5 Pairs 2 B, 1 RTB, 2 NBMonth 6 = 8 Pairs 3 B, 2 RTB, 3 NBMonth 7 = ?
Fibonacci
Month 4 = 3 Pairs 1 B 1 RTB 1 NBMonth 4 = 3 Pairs 1 B, 1 RTB, 1 NBMonth 5 = 5 Pairs 2 B, 1 RTB, 2 NBMonth 6 = 8 Pairs 3 B, 2 RTB, 3 NBMonth 7 = ?
CS 1410 - SJAllan Chapter 19 12
RuleNext term is the sum of the previous two
7
Fibonacci
Solution:Solution:In Month 1 and 2, there is 1 pairIn Month N > 2
Get the number of pairs in month N – 1Get the number of pairs in month N – 2Add them together to get number of pairs in month N
CS 1410 - SJAllan Chapter 19 13
Add them together to get number of pairs in month N
Notice this is recursive!
Fibonacci – Program
int Fibonacci( int n ){
if ( n <= 0 )return 0;
else if ( n == 1 )return 1;
else
CS 1410 - SJAllan Chapter 19 14
elsereturn Fibonacci( n-1 ) + Fibonacci( n-2 );
} // Fibonacci
8
Factorial
n! = n × (n-1) × (n-2) × … × 3 × 2 × 1
n! =
(n-1)!
(n-2)!
1 if n = 0 or n = 1
CS 1410 - SJAllan Chapter 19 15
n! = n × (n-1)!
Factorial – Program
int Factorial( int n ){{
if ( n < 0 )return 0;
else if ( n == 0 )return 1;
l
CS 1410 - SJAllan Chapter 19 16
elsereturn n * factorial( n – 1 );
} // Factorial
9
But Wait! – Isn’t there a better way?
int Factorial( int n ){ i t 0{ int sum = 0;
if ( n < 0 )return 0;
for ( int i = 1; i <= n; sum *= i++ );return sum;
CS 1410 - SJAllan Chapter 19 17
;} // Factorial
Recursion vs. IterationIteration can be used in place of recursion
Iterative algorithm uses a looping constructRecursive algorithm uses a branching construct
Recursion often takes more time and spacethan iteration
Less efficientRecursion often simplifies the solution of a
CS 1410 - SJAllan Chapter 19 18
Recursion often simplifies the solution of a problem, resulting in shorter, more easily understood source code
10
How Do We Write a Recursive Function?
Determine the size factorTo measure that sub-problems are smaller
Determine the base casesWhere answer is computed non-recursively
Determine the general casesAnswer expressed as smaller sub-problems of the same type
CS 1410 - SJAllan Chapter 19 19
ypVerify the algorithm
Use the Three-Question Method
The Three Question MethodThe Base-Case Question:
Is there a non-recursive way out of the function, d d th ti k tl f thi "b "and does the routine work correctly for this "base"
case?The Smaller-Caller Question:
Does each recursive call to the function involve a smaller case of the original problem, leading inescapably to the base case?
CS 1410 - SJAllan Chapter 19 20
The General-Case Question:Assuming that the recursive calls work correctly, does the whole function work correctly?
11
Another Example
Consider searching for a number in a sorted list
Binary searchExamine the middle element, is that the object?If not, is the middle larger, look into the first halfIf not look into the second half of the list
CS 1410 - SJAllan Chapter 19 21
If not, look into the second half of the list
Binary Searchint BinarySearch( int list[ ], int size, int value ){ int first = 0, last = size – 1, middle, position = -1;
for ( ; first <= last; )( ; ; ){ middle = ( first + last ) / 2;
if ( list[middle] == value )return middle;
else if ( list[middle] > valuelast = middle – 1;
else
CS 1410 - SJAllan Chapter 19 22
first = middle + 1;} // forreturn -1;
} // BinarySearch
12
Example of BinarySearch
Find ‘k’ in data = {a, b, c, e, h, k, l, m, z}St 1Step 1:
first = 0, last = 8, middle = 4, {a, b, c, e, h, k, l, m, z}{a, b, c, e} {h} {k, l, m, z}
Step 2:first = 5, last = 8, middle = 6, {k, l, m, z}{k} {l} {m, z}
CS 1410 - SJAllan Chapter 19 23
{k} {l} {m, z}
Step 3:first = 5, last = 5, middle = 5, {k}return 5
Recursive BinarySearchDetermine the size factor:
Determine the base cases:
Determine the general cases:
CS 1410 - SJAllan Chapter 19 24
13
Recursive BinarySearchDetermine the size factor:
Number of objects in a list to consider, i.e., list[first] … list[last]
D t i th bDetermine the base cases:Empty list, no solution found, i.e., first > lastThe current one is the sought object, i.e., list[middle] == value
Determine the general cases:The current one < the sought object
Since list is sorted, list[first] … list[index] < value, soE i l
CS 1410 - SJAllan Chapter 19 25
Examine only list[middle + 1] … list[last]The current one > the sought object
Since data is sorted, value < list[index] … list[last], soExamine only list[first] … list[middle - 1]
Recursive BinarySearch
int BinarySearch( int list[ ], int first, int last, int value ){ int middle;{ ;
if ( first > last )return -1;
middle = ( first + last ) / 2;if ( list[middle] == value )
return middle;else if ( value > list[middle] )
CS 1410 - SJAllan Chapter 19 26
return BinarySearch( list, middle + 1, last, value );else
return BinarySearch( list, first, middle - 1, value );} // BinarySearch
14
What are the Caveats with Recursion?
Let’s revisit the Fibonacci sequence:int Fibonacci( int n )int Fibonacci( int n ){
if ( n <= 0 )return 0;
else if ( n == 1 )return 1;
CS 1410 - SJAllan Chapter 19 27
return 1;else
return Fibonacci( n-1 ) + Fibonacci( n-2 );} // Fibonacci
Fibonacci Revisited
Fib(5)
Fib(4)
Fib(3) Fib(2)
Fib(1) Fib(0)Fib(2) Fib(1)
Fib(1) Fib(0)
Fib(3)
Fib(2) Fib(1)
Fib(1) Fib(0)
CS 1410 - SJAllan Chapter 19 28
Fib(1) Fib(0)
15
What is the Problem?
Memory expensiveTime expensiveExecution stack
For every new function an activation record needs to be pushed onto the stack…
CS 1410 - SJAllan Chapter 19 29
Stack for Fibonacci
n 3Fib ?
n 3Fib ?
n 2Fib ?
n 3Fib ?
n 2Fib ?
n 1Fib 1
n 3Fib ?
n 2Fib 1+?
n 0Fib 0
n 3Fib 1+?
n 1Fib 1
n 2Fib ?
n 2Fib ?
n 1Fib 1
n 2Fib 1+?
n 0Fib 0
CS 1410 - SJAllan Chapter 19 30
n 4Fib?
n 4Fib ?
n 4Fib ?
n 4Fib ?
n 4Fib ?
n 4Fib ?
n 4Fib 2+?
n 4Fib 2+?
n 4Fib 2+?
n 4Fib 3
16
When Should I Use Recursion?
When the depth of recursive calls is small,When the recursive version does similar amount of work as the non-recursive version,
andWhen the recursive version is shorter and simpler than the non-recursive approach
CS 1410 - SJAllan Chapter 19 31
simpler than the non recursive approach
Recursive Linked List Operations
Recursion may be used in some operations on linked listson linked lists.We will look at functions that:
Count the number of nodes in a list, andDisplay the value of the list nodes in reverse order.
CS 1410 - SJAllan Chapter 19 32
17
Counting the Nodes in a List
int NumberList::countNodes ( Node *nodePtr ){ if ( nodePtr ){ if ( nodePtr )
return 1 + countNodes( nodePtr->next );else
return 0;} // NumberList::countNodes
CS 1410 - SJAllan Chapter 19 33
Displaying the Nodes in Reverse Order
void NumberList::showReverse ( Node *nodePtr ){ if ( nodePtr ){ if ( nodePtr )
{ showReverse( nodePtr->next );cout << nodePtr->value << " ";
} // if} // NumberList::showReverse
CS 1410 - SJAllan Chapter 19 34
18
QuicksortCan be used to sort lists stored in arrays or linear linked listsIt sorts a list by dividing it into two sublists
Between the sublists is a selected value known as the pivotThis is illustrated below:
CS 1410 - SJAllan Chapter 19 35
QuickSort
Once a pivot value has been selected, the algorithm exchanges the other values in the g glist until all the elements in sublist 1 are less than the pivot, and all the elements in sublist 2 are greater than the pivotOnce this is done, the algorithm repeats the procedure on sublist 1, and then on sublist 2.
CS 1410 - SJAllan Chapter 19 36
The recursion stops when there is only one element in a sublist. At that point the original list is completely sorted
19
QuickSortvoid quickSort ( int set[], int start, int end ){ int pivotPoint;
if ( start < end ){ pivotPoint = partition( set, start, end );
quickSort( set, start, pivotPoint – 1 );quickSort( set, pivotPoint + 1, end );
} // if
CS 1410 - SJAllan Chapter 19 37
} // quickSort
QuickSortint partition ( int set[ ], int start, int end ){ int pivotValue, pivotIndex, mid;
mid = ( start + end ) / 2;swap( set[start], set[mid] );pivotIndex = start;pivotValue = set[start];for ( int scan = start + 1; scan <= end; scan++ )
if ( set[scan] < pivotValue ){ pivotIndex++;
swap( set[pivotIndex], set[scan] );
CS 1410 - SJAllan Chapter 19 38
p( [p ], [ ] );} // if
swap( set[start], set[pivotIndex] );return pivotIndex;
} // partition