You are on page 1of 14

CSE 326

Analyzing Recursion
David Kaplan
Dept of Computer Science & Engineering
Autumn 2001

Recursion Rules
Rules for using recursion effectively (Weiss 1.3):
1. Base cases Must have some non-recursive base case(s).
2. Making progress Recursive call must progress toward a
base case.
3. Design rule Assume the recursive calls work.
4. Compund interest rule Dont duplicate work in separate
recursive calls.

Analyzing Recursion

CSE 326 Autumn 2001

Recurrence Equations
A recursive procedure can often be analyzed by
solving a recurrence equation of the form:
T(n) =
base case: some constant
recursive case: T(subproblems) + T(combine)

Result depends upon


how many subproblems
how much smaller are subproblems
how costly to combine solutions (coefficients)

Analyzing Recursion

CSE 326 Autumn 2001

Example: Sum of Queue


SumQueue(Q)
if (Q.length == 0 )
return 0
else
return Q.dequeue() + SumQueue(Q)

One subproblem
Linear reduction in size (decrease by 1)
Combining: constant (cost of 1 add)
T(0) b
T(n) c + T(n 1)
Analyzing Recursion

for n>0

CSE 326 Autumn 2001

Sum of Queue Solution


Equation:
T(0) b
T(n) c + T(n 1)

for n>0

Solution:
T(n) c + c + T(n-2)
c + c + c + T(n-3)
kc + T(n-k) for all k
nc + T(0) for k=n
cn + b = O(n)

Analyzing Recursion

CSE 326 Autumn 2001

Example: Binary Search


Search a sorted array for a given item, x
If x == middle array element, return true
Else, BinarySearch lower (x<mid) or upper (x>mid) sub-array
1 subproblem, half as large
BinarySearch(A, x)
if (A.size == 1) return (x == A[0])
mid = A.size / 2
if (x == A[mid]) return true
else if (x < A[mid]) return BinarySearch( A_LowerHalf, x)
else if (x > A[mid]) return BinarySearch( A_UpperHalf, x)

Equation:
T(1) b
T(n) T(n/2) + c for n>1
Analyzing Recursion

CSE 326 Autumn 2001

Binary Search: Solution


Equation:
T(1) b
T(n) T(n/2) + c

for n>1

Solution:
T(n) T(n/2) + c
T(n/4) + c + c
T(n/8) + c + c + c
T(n/2k) + kc
T(1) + c log n where k = log n
b + c log n = O(log n)
Analyzing Recursion

CSE 326 Autumn 2001

Recursion Tree for

Binary Search
Problem size
n
n/2

Cost per stage


O(1)
O(1)

n/4

O(1)

log n

O(1)
(log n)

Analyzing Recursion

CSE 326 Autumn 2001

Example: MergeSort
Split array in half, sort each half, merge sub-arrays
2 subproblems, each half as large
linear amount of work to combine

T(n) 2T(n/2)+cn

2(2(T(n/4)+cn/2)+cn

= 4T(n/4) +cn +cn

4(2(T(n/8)+c(n/4))+cn+cn

= 8T(n/8)+cn+cn+cn 2kT(n/2k)+kcn
2kT(1) + cn log n

where k = log n

= O(n log n)
Analyzing Recursion

CSE 326 Autumn 2001

Recursion Tree for

Merge Sort

Problem size

Cost per stage

n
n/2

n/4

O(n)
n/2

n/4

O(n)

n/4

O(n)

log n

O(n)
(n log n)

Analyzing Recursion

CSE 326 Autumn 2001

10

Example: Recursive Fibonacci


Fibonacci numbers seems like a great use of recursion
Simple, elegant-looking recursive code
Fibonacci(i)
if (i == 0 or i == 1) return 1
else
return Fibonacci(i - 1) + Fibonacci(i - 2)

Analyzing Recursion

CSE 326 Autumn 2001

11

Fibonacci Call Tree


But what actually happens is combinatorial explosion
Fib(5)
Fib(4)

Fib(3)

Fib(3)

Fib(2)
Fib(1)

Fib(2)
Fib(0)

Fib(0)

Fib(1)

Fib(1)
Fib(1)
Fib(0)

Analyzing Recursion

CSE 326 Autumn 2001

Fib(2)

Fib(1)
12

Analyzing Recursive Fibonacci


Running time: Lower bound analysis
T(0), T(1) 1
T(n) T(n - 1) + T(n - 2) + c

if n > 1

Note: T(n) Fib(n)


Weiss shows in 1.2.5 that Fib(n) < (5/3)n
Similar logic shows that Fib(n) (3/2)n for N>4

In fact:
Fib(n) = ((3/2)n), Fib(n) = O((5/3)n), Fib(n) = (n)
where = (1 + 5)/2
Analyzing Recursion

CSE 326 Autumn 2001

13

Non-Recursive Fibonacci
Avoid recursive calls
Keep a table of calculated values
each time you calculate an answer, store it in the table

Before performing any calculation for a value n


check if a valid answer for n is in the table
if so, return it

Memoization
a form of dynamic programming

How much time does memoized Fibonacci take?

Analyzing Recursion

CSE 326 Autumn 2001

14

You might also like