Recursion • Recursion Divide a problem into subproblems of the same type Recursive function: a method (function) calling itself CSED233: Data Structures (2015F) Lecture8: Recursion • A classic example Factorial function ! 1 ⋅ 2 ⋅ ⋯⋅ 1 ⋅ Recursive definition Bohyung Han CSE, POSTECH [email protected] 1 ⋅ 4 4⋅ 3 4⋅3⋅ 4⋅3⋅2⋅1⋅1 2 1 if 0 otherwise 4⋅3⋅2⋅ 1 CSED233: Data Structures by Prof. Bohyung Han, Fall 2015 Visualizing Recursion int Factorial(int n) { if (n == 0) return 1; // base case else return n * Factorial(n ‐ 1); // recursive case } • Base case(s) Values of the input variables for which we perform no recursive calls There should be at least one base case Every possible chain of recursive calls must reach a base case. • Recursive case(s) Calls to the current method. Each recursive call should be defined so that it makes progress towards a base case. CSED233: Data Structures by Prof. Bohyung Han, Fall 2015 public void main(String args[]) { int fac; fac = 24 return 6*4=24 call Factorial(4) call fac = Factorial(4); System.out.println("fac = " + fac); return 2*3=6 Factorial(3) call 3 0 24 2 Recursive Function 4⋅3⋅2⋅1⋅ } return 1*2=2 int Factorial(int n) { return 1*1=1 if (n == 0) call return 1; Factorial(1) else call return 1 return n * Factorial(n ‐ 1); } Factorial(0) Factorial(2) Output: fac = 24 4 CSED233: Data Structures by Prof. Bohyung Han, Fall 2015 Reversing an Array Reversing an Array by Tail Recursion 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 ReverseArray(A, i+1, j‐1) Swap A[i] and A[j] return A 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 ReverseArray(A, 5, 11) ReverseArray(A, 6, 10) 3 6 1 9 4 2 7 i=j ReverseArray(A, 8, 8) 3 6 4 9 1 2 7 ReverseArray(A, 7, 9) i A linearly recursive method makes its recursive call as its last step. More efficient than ordinary recursions … A • Tail recursion j if i < j then Swap A[i] and A[j] ReverseArray(A, i+1, j‐1) return A A 3 2 4 9 1 6 7 i j ReverseArray(A, 6, 10) A A 7 2 4 9 1 6 3 i j ReverseArray(A, 5, 11) A 5 Recursive call is the last step in the method! ReverseArray(A, 5, 11) 7 6 1 9 4 2 3 i j 7 2 1 9 4 6 3 i j 7 2 4 9 1 6 3 i j ReverseArray(A, 6, 10) ReverseArray(A, 7, 9) 6 CSED233: Data Structures by Prof. Bohyung Han, Fall 2015 Recursion vs. Loop CSED233: Data Structures by Prof. Bohyung Han, Fall 2015 Computing Powers • Equivalence between recursion and loop • Objective A recursive function can be implemented with a loop. 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 , Compute the power function, Define recursively , 2,3 2⋅ 2,2 ⋅ 2⋅2⋅ 1 , 1 2,1 if 0 otherwise 2⋅2⋅2⋅ 2,0 2 8 • Time complexity • Comparisons Recursive function is simple and easy to understand. Loop is typically faster since it involves less system overhead. 7 CSED233: Data Structures by Prof. Bohyung Han, Fall 2015 : making recursive calls We can do better than this, however. 8 CSED233: Data Structures by Prof. Bohyung Han, Fall 2015 Recursive Squaring Recursive Squaring • A better method to compute powers Algorithm Power(x, n): Input: A number x and integer n = 0 Output: The value xn We can derive a more efficient linearly recursive algorithm by using repeated squaring , ⋅ , 1 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 if 0 if isodd if iseven 1 /2 , /2 For example 2 2⋅ 2 2⋅ 2⋅ 2 2⋅ 2⋅ 1 2⋅ 2 2⋅ 2 2⋅4 2 ⋅ 16 32 ⋅ , 9 Each time we make a recursive call we halve the value of ; hence, we make recursive calls. That is, this time. , It is important that we use a variable twice here rather than calling the method twice. 1 1 /2 , /2 if 0 if isodd if iseven Time complexity: 10 CSED233: Data Structures by Prof. Bohyung Han, Fall 2015 Binary Recursion log CSED233: Data Structures by Prof. Bohyung Han, Fall 2015 Fibonacci Number • What is binary recursion? Fibonacci(n) There are two recursive calls for each non‐base case. • Example Fibonacci number Fibonacci(n‐1) 1 2 if 0or 2 1 Fibonacci(n‐2) int Fibonacci(int n) { if (n == 0 || n == 1) return n; else return Fibonacci(n‐1) + Fibonacci(n‐2); } 11 Fibonacci(n‐2) … Fibonacci(n‐3) Fibonacci(n‐3) … … … … Time complexity: Fibonacci(n‐4) … … … 2 However, there are too many duplicate calls! CSED233: Data Structures by Prof. Bohyung Han, Fall 2015 12 CSED233: Data Structures by Prof. Bohyung Han, Fall 2015 A Better Fibonacci Algorithm Algorithm LinearFibonacci(k) Input: A nonnegative integer k Output: Pair of Fibonacci numbers (Fk , Fk‐1) LinearFibonacci(n) LinearFibonacci(n‐1) if k = 1 then return (1, 0) else (i, j) = LinearFibonacci(k – 1) return (i+j, i) LinearFibonacci(n‐2) … (5,3) = LinearFibonacci(5) (3,2) = LinearFibonacci(4) (2,1) = LinearFibonacci(3) LinearFibonacci(1) (1,1) = LinearFibonacci(2) No duplicate calls! (1,0) = LinearFibonacci(1) Time complexity: 13 CSED233: Data Structures by Prof. Bohyung Han, Fall 2015 14
© Copyright 2026 Paperzz