1 / 37

Introduction to Recursion

Introduction to Recursion. CSCI 3333 Data Structures. by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu http://sce.uhcl.edu/yue/ 2013. Acknowledgement. Mr. Charles Moen Dr. Wei Ding Ms. Krishani Abeysekera Dr. Michael Goodrich. Recursion.

zia-chang
Télécharger la présentation

Introduction to 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. Introduction to Recursion CSCI 3333 Data Structures byDr. Bun YueProfessor of Computer Scienceyue@uhcl.eduhttp://sce.uhcl.edu/yue/2013

  2. Acknowledgement • Mr. Charles Moen • Dr. Wei Ding • Ms. Krishani Abeysekera • Dr. Michael Goodrich

  3. Recursion • Recursion is a way to combat complexity and solve problems. • Solving a problem by: • solving the problem for ‘trivial’ cases, and • solving the same problem, but with smaller sizes.

  4. Recursive Definition • A recursive definition: a definition in terms of itself. Example: • 0 is a natural number. • If x is a natural number, then x+1 is a natural number. (or x is a natural number if x-1 is a natural number).

  5. Mathematical Induction • Proof by Induction is recursive in nature. • To prove S(n) for all n = 1, 2, 3. • Show: • S(n) is true for n = 1. • If S(k) is true for all k from 1 to n-1, then S(n) is true

  6. Recursive Methods • A recursive method may call itself. Example: factorial. Iterative definition: n! = n . (n-1) . (n-2) … 3 . 2 . 1 Recursive definition:

  7. Factorial Implementation: Fac-1 • Found here in C++: int factorial(int number) { int temp; if (number <= 1) return 1; temp = number * factorial(number - 1); return temp; } • What do you think?

  8. Another Implementation: Fac-2 // recursive factorial function in Java: public static int recursiveFactorial(int n) { if (n == 0) return 1; // base case else return n * recursiveFactorial(n- 1); // recursive case } // By Goodrich • What do you think?

  9. Content of a Recursive Method • Base case(s): exit conditions • Values of the input variables (exit conditions) for which we perform no recursive calls are called base cases (there should be at least one base case). • Every possible chain of recursive calls must eventually reach a base case. • Recursive calls: recursive conditions • Calls to the current method. • Each recursive call should be defined so that it makes progress towards a base case.

  10. return 4 * 6 = 24 final answer call recursiveFactorial ( 4 ) return 3 * 2 = 6 call recursiveFactorial ( 3 ) return 2 * 1 = 2 call recursiveFactorial ( 2 ) return 1 * 1 = 1 call recursiveFactorial ( 1 ) return 1 call recursiveFactorial ( 0 ) Visualizing Recursion Example recursion trace: • Recursion trace • A box for each recursive call • An arrow from each caller to callee • An arrow from each callee to caller showing return value

  11. Tips on Recursive Analysis • Identify exit and recursive conditions. • Ensure that the conditions cover all input ranges.

  12. Input Range Analysis of Fac • Fac-1 and Fac-2: n (or number) has the type of int. • Fac-2 may be caught in circularity forever for negative numbers. • This is especially serious in Java as it does not support unsigned int.

  13. Complexity Analysis • To analyze the time complexity of a recursive routine, a recurrence relation may need to be identified and solved. • E.g. for factorial: T(0) = d T(N) = T(N-1) + c Solving by substitution: T(N) = cN + d = O(N)

  14. Reversing an Array Algorithm ReverseArray(A, i, j): Input: An array A and nonnegative integer indices i and j Output: The reversal of the elements in A starting at index i and ending at j if i < j then Swap A[i] and A[ j] ReverseArray(A, i + 1, j - 1) end if; return;

  15. Tips on Constructing Recursion • In creating recursive methods, it is important to define the methods in ways that facilitate recursion. • This sometimes requires that we may define additional parameters that are passed to the method. • For example, we defined the array reversal method as ReverseArray(A, i, j), not ReverseArray(A).

  16. Implementation in Java public static void arrayReversal (int[] a) { arrayReversalWithRange(a, 0, a.length-1); } private static void arrayReversalWithRange (int[] a, int i, int j) { if (i < j) { int temp = a[i]; a[i] = a[j]; a[j] = temp; arrayReversalWithRange(a,i+1,j-1); } }

  17. Calling arrayReversal public static void main (String args[]) { int b[] = {1,2,3,4,5,6,7}; arrayReversal(b); for (int i=0; i<b.length; i++) { System.out.println(b[i] + " "); } }

  18. Computing Powers • The power function, p(x,n)=xn, can be defined recursively: • This leads to an power function that runs in linear time (for we make n recursive calls). • We can do better than this, however.

  19. Recursive Squaring • We can derive a more efficient linearly recursive algorithm by using repeated squaring: • For example, 24= 2(4/2)2 = (24/2)2 = (22)2 = 42 = 16 25= 21+(4/2)2 = 2(24/2)2 = 2(22)2 = 2(42) = 32 26= 2(6/ 2)2 = (26/2)2 = (23)2 = 82 = 64 27= 21+(6/2)2 = 2(26/2)2 = 2(23)2 = 2(82) = 128.

  20. A Recursive Squaring Method Algorithm Power(x, n): Input: A number x and integer n Output: The value xn if n = 0 then return 1 if n is odd then y = Power(x, (n - 1)/ 2) return x · y · y else y = Power(x, n/ 2) return y · y

  21. Analyzing the Recursive Squaring Method Algorithm Power(x, n): Input: A number x and integer n Output: The value xn if n = 0 then return 1 if n is odd then y = Power(x, (n - 1)/ 2) return x · y · y else y = Power(x, n/2) return y · y Each time we make a recursive call we halve the value of n; hence, we make log n recursive calls. That is, this method runs in O(log n) time. It is important that we used a variable twice here rather than calling the method twice.

  22. Further Analysis • Need to limit the range of n, or. • Add the recursive condition: if n < 0 return 1 / Power(x, -n);

  23. Tail Recursion 1 • Tail recursion occurs when a linearly recursive method makes its recursive call as its last step. • The array reversal method is an example. • Such methods can easily be converted to non-recursive methods (which saves on some resources), often by the compiler and runtime system.

  24. Tail Recursion Example Algorithm IterativeReverseArray(A, i, j ): Input: An array A and nonnegative integer indices i and j Output: The reversal of the elements in A starting at index i and ending at j while i < j do Swap A[i ] and A[ j ] i = i + 1 j = j - 1 return

  25. Tail Recursion 2 • Tips: for linear recursion, write your method using tail recursion. • Example: Fac-1 does not use tail recursion. Fac-2 does.

  26. Binary Recursion • Binary recursion occurs whenever there are two recursive calls for each non-base case. • Example: the DrawTicks method for drawing ticks on an English ruler.

  27. A Binary Recursive Method for Drawing Ticks // draw a tick with no label public static void drawOneTick(int tickLength) { drawOneTick(tickLength, - 1); } // draw one tick public static void drawOneTick(int tickLength, int tickLabel) { for (int i = 0; i< tickLength; i++) System.out.print("-"); if (tickLabel >= 0) System.out.print(" " + tickLabel); System.out.print("\n"); } public static void drawTicks(int tickLength) { // draw ticks of given length if (tickLength > 0) { // stop when length drops to 0 drawTicks(tickLength- 1); // recursively draw left ticks drawOneTick(tickLength); // draw center tick drawTicks(tickLength- 1); // recursively draw right ticks } } public static void drawRuler(int nInches, int majorLength) { // draw ruler drawOneTick(majorLength, 0); // draw tick 0 and its label for (int i = 1; i <= nInches; i++) { drawTicks(majorLength- 1); // draw ticks for this inch drawOneTick(majorLength, i); // draw tick i and its label } } Note the two recursive calls

  28. Binary Recursion • Binary Recursions are expensive. • If possible, convert it to linear recursion.

  29. Fibonacci Numbers • Fibonacci numbers are defined recursively: F0= 0 F1= 1 Fi= Fi-1+ Fi-2 for i > 1.

  30. Recursive Fibonacci Algorithm Algorithm BinaryFib(k): Input: Nonnegative integer k Output: The kth Fibonacci number Fk if k = 1 then return k else return BinaryFib(k - 1) + BinaryFib(k - 2) • Binary recursion from Goodrich’s book. • Any problem here?

  31. A C++ Implementation long fib(unsigned long n) { if (n <= 1) { return n; } else { return fib(n-1)+fib(n-2); } }

  32. Fibonacci Number • Negative Fibonacci Number: • F-1 = 1, • F-2 = -1, • Fn = F(n+2)−F(n+1). • 1,-1,2,-3,5,-8,13,…

  33. Analyzing the Binary Recursion Fibonacci Algorithm • Let nk denote number of recursive calls made by BinaryFib(k). Then • n0 = 1 • n1 = 1 • n2 = n1 + n0 + 1 = 1 + 1 + 1 = 3 • n3 = n2 + n1 + 1 = 3 + 1 + 1 = 5 • n4 = n3 + n2 + 1 = 5 + 3 + 1 = 9 • n5 = n4 + n3 + 1 = 9 + 5 + 1 = 15 • n6 = n5 + n4 + 1 = 15 + 9 + 1 = 25 • n7 = n6 + n5 + 1 = 25 + 15 + 1 = 41 • n8 = n7 + n6 + 1 = 41 + 25 + 1 = 67. • Note that the value at least doubles for every other value of nk. That is, nk > 2k/2. It is exponential!

  34. A Better Fibonacci Algorithm • Use linear recursion instead: Algorithm LinearFibonacci(k): Input: A nonnegative integer k Output: Pair of Fibonacci numbers (Fk, Fk-1) if k = 1 then return (k, 0) else (i, j) =LinearFibonacci(k - 1) return (i +j, i) • Runs in O(k) time.

  35. Implementation • Java and C++ do not return multiple values. • Perl’s implementation: sub fib { return (1,0) if $_[0] == 1; my ($i, $j) = fib($_[0]-1); return ($i+$j, $i); } print "fib(13): " + fib(13) + "\n";

  36. Java implementation public static int Fab(int n) { if (n <= 2) return 1; return FabHelper(n,2,1,1); } private static int FabHelper(int n, int k, int fk, int fk_1) { if (n == k) return fk; else return FabHelper(n, k+1, fk + fk_1, fk); }

  37. Questions and Comments?

More Related