140 likes | 149 Views
This text discusses the rules for using recursion effectively, solving recurrence equations, and analyzes examples like Sum of Queue, Binary Search, and Fibonacci.
E N D
CSE 326Analyzing Recursion David Kaplan Dept of Computer Science & Engineering Autumn 2001
Recursion Rules Rules for using recursion effectively (Weiss 1.3): • Base cases Must have some non-recursive base case(s). • Making progress Recursive call must progress toward a base case. • Design rule Assume the recursive calls work. • Compund interest rule Don’t duplicate work in separate recursive calls. CSE 326 Autumn 2001 2
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) CSE 326 Autumn 2001 3
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) for n>0 CSE 326 Autumn 2001 4
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) CSE 326 Autumn 2001 5
Example: Binary Search 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) 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 Equation: T(1) b T(n) T(n/2) + c for n>1 CSE 326 Autumn 2001 6
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) CSE 326 Autumn 2001 7
Recursion Tree for Binary Search Problem size Cost per stage n O(1) n/2 O(1) n/4 O(1) log n … … 1 O(1) Θ(log n) CSE 326 Autumn 2001 8
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) CSE 326 Autumn 2001 9
Recursion Tree for Merge Sort Problem size Cost per stage n O(n) n/2 n/2 O(n) n/4 n/4 n/4 O(n) log n … … … … 1 1 1 O(n) Θ(n log n) 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) 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(2) Fib(1) Fib(1) Fib(2) Fib(0) Fib(1) Fib(0) Fib(1) Fib(1) Fib(0) CSE 326 Autumn 2001 12
Analyzing Recursive Fibonacci • Running time: Lower bound analysis T(0), T(1) 1 T(n) T(n - 1) + T(n - 2) + c ifn > 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 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? CSE 326 Autumn 2001 14