Lecture8 - POSTECH Computer Vision Lab

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