csc 221: recursion
DESCRIPTION
CSC 221: Recursion. Recursion: Definition. Function that solves a problem by relying on itself to compute the correct solution for a smaller version of the problem Requires terminating condition : Case for which recursion is no longer needed. Recursion: Induction Basis. - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/1.jpg)
CSC 221: Recursion
![Page 2: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/2.jpg)
Recursion: Definition
• Function that solves a problem by relying on itself to compute the correct solution for a smaller version of the problem
• Requires terminating condition: Case for which recursion is no longer needed
![Page 3: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/3.jpg)
Recursion: Induction Basis
• Mathematical Induction:– Prove that statement is true for first n values,
given that it is true for first n-1 values– Prove that the statement is true for a base
case.
![Page 4: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/4.jpg)
Recursion: Mathematical Induction
• Sum of first N positive integers is (N*(N+1)) / 2• Base Case:
– 1st positive integer 1
(1 * (1+1)) / 2 =>(1*2)/2 => 2/2 => 1
• Inductive Case: Assume true for n-1– Sum(1..N-1) = ((N-1) * (N-1+1)) / 2 => ((N-1) * (N)) / 2)
= (N2 –N)/2– Adding N = (N2 –N)/2 + N
= (N2-N)/2 + 2N/2
= (N2 + N)/2 => (N * (N+1)) / 2
![Page 5: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/5.jpg)
Factorial Recursion
• Factorial: n! = n * (n-1)!– Base Case => 0! = 1– Smaller problem => Solving (n-1)!
• Implementation:
long factorial(long inputValue)
{
if (inputValue == 0) return 1;
else return inputValue * factorial(inputValue - 1);
}
![Page 6: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/6.jpg)
Searching
• We want to find whether or not an input value is in a sorted list:
8 in [1, 2, 8, 10, 15, 32, 63, 64]?
33 in [1, 2, 8, 10, 15, 32, 63, 64]?
![Page 7: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/7.jpg)
Searching
int index = 0;
while (index < listSize)
{
if (list[index] == input) return index;
index++;
}
return –1;
![Page 8: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/8.jpg)
Searching
• Better method:– Number of operations to find input if in the list:
• Dependent on position in list• 1 operation to size of list
– Number of operations to find input if not in the list:
• Size of list
![Page 9: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/9.jpg)
Searching
• Better method? • Use fact that we know the list is sorted• Cut what we have to search in half each time
– Compare input to middle– If input greater than middle, our value has be in the
elements on the right side of the middle element– If input less than middle, our value has to be in the
elements on the left side of the middle element– If input equals middle, we found the element.
![Page 10: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/10.jpg)
Searching: Binary Search
for (int left = 0, right = n –1; left <= right;)
{
middle =(left + right) / 2;
if (input == list[middle]) return middle;
else if (input < list[middle]) right = middle – 1;
else left = middle + 1;
}
return – 1;
![Page 11: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/11.jpg)
Searching: Binary Search
8 in [1, 2, 8, 10, 15, 32, 63, 64]?1st iteration:
Left = 0, Right = 7, Middle = 3, List[Middle] = 10Check 8 == 10 => No, 8 < 10
2nd iteration:Left = 0, Right = 2, Middle = 1, List[Middle] = 2Check 8 == 2 => No, 8 > 2
3rd iteration:Left = 2, Right = 2, Middle = 2Check 8 == 8 => Yes, Found It!
![Page 12: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/12.jpg)
Searching: Binary Search
• Binary Search Method:– Number of operations to find input if in the list:
• Dependent on position in list• 1 operation if middle
• Log2 n operations maximum
– Number of operations to find input if not in the list:
• Log2 n operations maximum
![Page 13: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/13.jpg)
Recursive Binary Search
• Two requirements for recursion:– Same algorithm, smaller problem– Termination condition
• Binary search?– Search in half of previous array– Stop when down to one element
![Page 14: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/14.jpg)
Recursive Binary Search
int BinarySearch(int *list, const int input, const int left, const int right)
{if (left < right){
middle =(left + right) / 2;if (input == list[middle]) return middle;else if (input < list[middle]) return BinarySearch(list,
input, left, middle-1);else return BinarySearch(list,input,middle+1,right);
}return – 1;}
![Page 15: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/15.jpg)
While vs Recursion
• While and Recursion are essentially interchangeable
• Considerations:– Efficiency– Simplification of programming– Readability/Understandability
• While they are equivalent, there is not always an obvious while implementation of some functions that are easily implemented with recursion
![Page 16: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/16.jpg)
Fibonacci Computation
• Fibonacci Sequence:– 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, …– Simple definition:– Fib[0] = 1– Fib[1] = 1– Fib[N] = Fib(N-1) + Fib(N-2)
![Page 17: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/17.jpg)
Recursive Fibonacci
int fibonacci(int input)
{
if ((input == 0) || (input == 1)) return 1;
else return (fibonacci(input-1) + fibonacci(input-2));
}
![Page 18: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/18.jpg)
Iterative Fibonacciint fibonacci(int input){ int first = 1; int second = 1;
int temp; for (int k = 0; k < input; k++) { temp = first; first = second; second = temp + second; } return first;}
![Page 19: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/19.jpg)
Efficiency of Recursion
• Recursion can sometimes be slower than iterative code
• Two main reasons:– Program stack usage– Result generation
![Page 20: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/20.jpg)
Types of Recursion
• Linear Recursion:– 1 recursive call per function– Factorial, Binary Search examples
• Tree Recursion:– 2 or more recursive calls per function– Fibonacci Example
![Page 21: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/21.jpg)
Efficiency of Recursion
• Stack Usage:– When a function is called by a program, that
function is placed on the program call stack:
main()
getData()
readFile()Returns file data to be used in getData()
Returns formatted data to be printed in main()
![Page 22: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/22.jpg)
Efficiency of Recursion
• Every stack entry maintains information about the function:– Where to return to when the function
completes– Storage for local variables– Pointers or copies of arguments passed in
![Page 23: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/23.jpg)
Efficiency of Recursion
• When using recursive functions, every recursive call is added to the stack and it grows fast:
• Fibonacci (5)– Fibonacci (5) = Fibonacci (4) + Fibonacci(3)– Fibonacci (1) in the computation of Fibonacci(4) is the first time we don’thave to call the function again.
• Stack entries take up space and require extra processing
main()
Fibonacci(5)
Fibonacci(4)
Fibonacci(3)
Fibonacci(2)
Fibonacci(1)
![Page 24: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/24.jpg)
Efficiency of Recursion• Another Reason for Slowdowns [Tree Recursion]
– Traditional Recursion doesn’t save answers as it executes– Fib(5) = Fib(4) + Fib(3)= Fib(3) + Fib(2) + Fib(3)= Fib(2) + Fib(1) + Fib(2) + Fib(3)= Fib(1) + Fib(0) + Fib(1) + Fib(2) + Fib(3)= Fib(1) + Fib(0) + Fib(1) + Fib(1) + Fib(0) + Fib(3)= Fib(1) + Fib(0) + Fib(1) + Fib(1) + Fib(0) + Fib(2) + Fib(1)= Fib(1) + Fib(0) + Fib(1) + Fib(1) + Fib(0) + Fib(1) + Fib(0) + Fib(1)
• Solution: Dynamic programming – saving answers as you go and reusing them
![Page 25: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/25.jpg)
Dynamic Programming
• Fibonacci Problem– We know the upper bound we are solving for– Ie Fibonacci (60) = 60 different answers– Generate an array 60 long and initalize to –1– Everytime we find a solution, fill it in in the
array– Next time we look for a solution, if the value in
the array for the factorial we need is not –1, use the value present.
![Page 26: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/26.jpg)
Fibonacci Examples
• Three implementations of fibonacci:– Naive recursion implementation
(worst performance)– Dynamic Programming recursion
implementation (better)– Iterative implementation
(best)
![Page 27: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/27.jpg)
Recursive Datastructures
• Recursion is useful when datastructure is inherently recursive
• Unix directory hierarchy is a tree datastructure
/
/home/var /usr
/home/turketwh
/home/turketwh/CS112 /home/turketwh/CS221
![Page 28: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/28.jpg)
Directory Traversal
• ls –R in Unix => recursive list• Potential implementation?
– listDirectory(directory baseDirectory){
file[] files = getFiles();int fileCount = getFileCount();for (int i = 0; i < fileCount; i++){if (files[I].type == “dir”) listDirectory(file);else listFile(file);}
}
![Page 29: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/29.jpg)
Recursive Datastructures
• Will see a lot of datastructures that are recursive – Lists [Atom + Smaller List]– Trees [ Root + Subtrees]
• Have simple implementations because their functionality can be defined recursively.
![Page 30: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/30.jpg)
Towers of Hanoi
Not allowed
General Problem: For any number of boxes, move boxes from start peg to destination peg. Can never place a bigger box on top of a smaller box.
![Page 31: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/31.jpg)
Towers Of Hanoi
• Recursive?
• 1 box from peg 1 to peg 3
1 _ __ _ 1
• 2 boxes from peg 1 to peg 3
1 1
2 _ _ 2 1 _ _ 1 2 _ _ 2
![Page 32: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/32.jpg)
Towers Of Hanoi
• 3 boxes from peg 1 to peg 312 2 1 13 _ _ 3 _ 1 3 2 1 3 2 _
_ 2 3
1 2 2
1 2 3 1 _ 3 _ _ 3
For n boxes,
1) Solve the n-1 problem from start to the temp peg
2) Move the nth box to the destination peg
3) Solve the n-1 problem from the temp peg to the destination peg
![Page 33: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/33.jpg)
Space Efficiency
• Factorial(N)– Factorial(4) =>
= 4*Factorial(3)= 4 * 3 * Factorial(2)= 4 * 3 * 2 * Factorial(1)= 4 * 3 * 2 * 1
– Has to make a maximum of N calls before base case is reached and function returns.
– N activation records will be placed on the stack.
• Since the size of the input is N, this function requires memory that is linearly related to the size of the input
![Page 34: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/34.jpg)
Space Efficiency• Fibonacci(N) – Standard recursive
implementation– Fib(5) = Fib(4) + Fib(3)– For Fib(4), also puts Fib(3),Fib(2), Fib(1) on stack– For Fib(3), also puts Fib(2), Fib(1) on stack– Fib(4), Fib(3) compute separately
• Space Efficiency considers maximum amount required at one time – Fib(4) branch in this case
• Requires memory linearly related to input size
![Page 35: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/35.jpg)
Tail RecursionTail Recursion: When the results of a recursive call are not used after
the recursive call within the calling function.
long factorialHelper(long startValue, long inputValue){
if (startValue == 0) return 1; else if (inputValue == 1) return startValue; else return factorialHelper(startValue * (inputValue-1),
inputValue - 1);}
long factorial(long inputValue){
return factorialHelp(inputValue, inputValue);}
![Page 36: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/36.jpg)
Space Efficiency: Tail Recursion
• Since the results of the recursive call aren’t needed for other computations, the stack frames aren’t needed to hold partial results.
• With each call, new frame replaces old frame.– The compiler handles these optimizations.
• Requires constant amount of memory and is not dependent on the size of the input.
![Page 37: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/37.jpg)
Space Efficiency: Tail Recursion
main()
factorialHelper(3,3)
factorialHelper(6,2)
factorialHelper(6,1)
Without Optimization
Return 6
Return 6
Return 6Call
Call
Call
With Optimization looks like this:(each call of fh is done when it calls the next, so take it off the stack)
main()
factorialHelper(3,3)
main()
factorialHelper(6,2)
main()
factorialHelper(6,1)
![Page 38: CSC 221: Recursion](https://reader035.vdocument.in/reader035/viewer/2022070404/56813b29550346895da3ea46/html5/thumbnails/38.jpg)
Recursion • Key Ideas
– Decomposition: Solve smaller problem(s) and combine answers
– Tends to allow for very simple writing of code – Used naively, may lead to
• Significant stack usage• Repeated computations
– Have touched on methodologies to help work around those issues:
• Tail Recursion• Storing answers (‘dynamic programming’)
– Suggests a new technique may be needed for computing number of operations for algorithm to complete