CS 310 Advanced Data Structures and Algorithms Recursion June 27, - - PowerPoint PPT Presentation

cs 310 advanced data structures and algorithms
SMART_READER_LITE
LIVE PREVIEW

CS 310 Advanced Data Structures and Algorithms Recursion June 27, - - PowerPoint PPT Presentation

CS 310 Advanced Data Structures and Algorithms Recursion June 27, 2017 Tong Wang UMass Boston CS 310 June 27, 2017 1 / 20 Recursion Recursion means defining something, such as a function, in terms of itself Recursion is a powerful


slide-1
SLIDE 1

CS 310 – Advanced Data Structures and Algorithms

Recursion June 27, 2017

Tong Wang UMass Boston CS 310 June 27, 2017 1 / 20

slide-2
SLIDE 2

Recursion

Recursion means defining something, such as a function, in terms of itself Recursion is a powerful problem-solving technique that often produces very clean solutions. Recursive solutions can be easier to understand and to describe than iterative solutions. Basic rules:

Base case: Always have at least one case that can be solved without recursion Make progress: Any recursive call must progress toward a base case Always assume that the recursive call works Never duplicate work by solving the same instance of a problem in separate recursive calls

Tong Wang UMass Boston CS 310 June 27, 2017 2 / 20

slide-3
SLIDE 3

Background: Proof by Mathematic Induction

Establish the basis

the basis is the easy case that can be shown by hand.

Assume the hypothesis

assumes that the theorem is true for some arbitrary case and that, under this assumption, it is true for the next case.

Demonstrate the induction Example: n

i=1 i = n(n+1) 2

base case: it is obvious true when N = 1. inductive hypothesis: assume it is true for N = k. when N = k + 1, k+1

i=1 i = (k + 1) + k(k+1) 2

= (k+1)(k+2)

2

Proofs by induction show us that: if we know that a statement is true for a smallest case and can show that one case implies the next case, then we know the statement is true for all cases.

Tong Wang UMass Boston CS 310 June 27, 2017 3 / 20

slide-4
SLIDE 4

Simple Example

S(N) be the sum of the first N integers S(1) = 1, S(N) = S(N - 1) + N The above is identical to the closed form S(N) = N(N + 1) / 2

Textbook Figure 7.1

Tong Wang UMass Boston CS 310 June 27, 2017 4 / 20

slide-5
SLIDE 5

How it works

Use an internal stack of activation records for recursion.

an activation record contains relevant information about the method, including, for instance, the values of the parameters and local variables.

The stack of activation records is used because methods return in reverse order of their invocation.

Textbook Figure 7.5

Tong Wang UMass Boston CS 310 June 27, 2017 5 / 20

slide-6
SLIDE 6

Why it works

A recursive solution solves a problem by solving a smaller instance of the same problem. When designing a recursive algorithm, we can always assume that the recursive calls work. Because when a proof is performed, this assumption is used as the inductive hypothesis. Recursive algorithms can be proven correct with mathematical induction.

Tong Wang UMass Boston CS 310 June 27, 2017 6 / 20

slide-7
SLIDE 7

Simple Example

factorial(n) iterative (function does not call itself)

if n = 0, factorial(n) = 1 if n > 0, factorial(n) = n*(n-1)*(n-2)...1

recursive (function call itself)

if n = 0, factorial(n) = 1 if n > 0, factorial(n) = n*factorial(n-1)

Tong Wang UMass Boston CS 310 June 27, 2017 7 / 20

slide-8
SLIDE 8

Iteration vs Recursion

/* iterative */ int factorial(int n) { int i = 1; int res = 1; while(i <= n) { res *= i; i += 1; } return res; }

straightforward, loop through n iterative solution is computed from small to big in general

/* recursive */ int factorial(int n) { if(n == 0) return 1; else return n*factorial(n-1); }

simple, eliminate the loop recursive solution is computed from big to small in general

Tong Wang UMass Boston CS 310 June 27, 2017 8 / 20

slide-9
SLIDE 9

Iteration vs Recursion

Depends what you are trying to do Recursion makes a program more elegant and readable (tree traversal) But it needs extra stack space for activation records Too much recursion can be dangerous Recursion is truly valuable when a program has no simple iterative solution

Tong Wang UMass Boston CS 310 June 27, 2017 9 / 20

slide-10
SLIDE 10

Fibonacci Numbers

Fibonacci numbers: 0, 1, 1, 2, 3, 5, 8, . . . F(0) = 0 F(1) = 1 (It has two base cases) F(n) = F(n − 1) + F(n − 2), for n ≥ 2 Closed form of Fibonacci numbers α = 1 + √ 5 2 β = 1 − √ 5 2 Fn = αn − βn √ 5

Tong Wang UMass Boston CS 310 June 27, 2017 10 / 20

slide-11
SLIDE 11

Too Much Recursion

// Compute the n-th Fibonacci number // Bad algorithm public static void fib( int n ) { if (n == 0) return 0; if (n == 1) return 1; else return fib( n-1 ) + fib( n-2 ); }

Let C(n) be the number of calls to fib() made during the evaluation of fib(n) C(0) = C(1) = 1 C(n) = C(n − 1) + C(n − 2) + 1 C(n) = F(n + 2) + F(n − 1) − 1 Prove by induction

Tong Wang UMass Boston CS 310 June 27, 2017 11 / 20

slide-12
SLIDE 12

Textbook Figure 7.7

Tong Wang UMass Boston CS 310 June 27, 2017 12 / 20

slide-13
SLIDE 13

Example

int s1, s2; int fib(n) { if(n == 0) return 0; else if(n == 1) return 1; else { s1 = fib(n - 1); s2 = fib(n - 2); return s1 + s2; } }

Consider the above program fib(2) = 1 fib(3) = 2 fib(4) = 2 ??

Tong Wang UMass Boston CS 310 June 27, 2017 13 / 20

slide-14
SLIDE 14

Example

This is a mistake, even though the function looks fine Its correctness crucially depends on having local variables for storing all the intermediate results If we move the declaration s1 and s2 inside the function, it will work perfectly This kind of bug is hard to find

Tong Wang UMass Boston CS 310 June 27, 2017 14 / 20

slide-15
SLIDE 15

Tail Recursion

Recursive methods are either tail recursive or non-tail recursive Tail recursive method has the recursive call as the last operation in the method It is more efficient because we do not need the call stack It is easy to convert tail recursive to iterative

Tong Wang UMass Boston CS 310 June 27, 2017 15 / 20

slide-16
SLIDE 16

Non-tail Recursion vs Tail Recursion

/* non-tail recursion */ int factorial(int n) { if(n == 0) return 1; else return n*factorial(n-1); } /* tail recursion */ int factorial(int n) { return helper(n, 1); } int helper(int n, int res) { if (n > 0) { return helper(n - 1, n * res); } return res; }

Tong Wang UMass Boston CS 310 June 27, 2017 16 / 20

slide-17
SLIDE 17

Numerical Applications

Modular arithmetic Modular exponentiation GCD

Tong Wang UMass Boston CS 310 June 27, 2017 17 / 20

slide-18
SLIDE 18

Modular Arithmetic

Theorems

1

If A ≡ B ( mod N), then for any C, A + C ≡ B + C ( mod N)

2

If A ≡ B ( mod N), then for any D, AD ≡ BD ( mod N)

3

If A ≡ B ( mod N), then for any positive P, AP ≡ BP ( mod N)

What is the last digit in 33335555? There are more than 15,000 digits, too prohibitive to compute directly Wanted: 33335555 ( mod 10) 3333 ≡ 3 ( mod 10), thus we only need 35555 ( mod 10) 34 = 81, 34 ≡ 1 ( mod 10) (34)1388 = 35552 ≡ 1 ( mod 10) 35555 ≡ 27 ≡ 7 ( mod 10)

Tong Wang UMass Boston CS 310 June 27, 2017 18 / 20

slide-19
SLIDE 19

Modular Exponentiation

How to compute xn ( mod p) when n is huge? Take ( mod p) for intermediate results – keep the numbers small If n is even, xn = (x · x)⌊ n

2 ⌋

If n is odd, xn = x · (x · x)⌊ n

2 ⌋

Let M(n) be the number of multiplications used by power M(n) ≤ M(⌊n/2⌋) + 2 log(n) algorithm

// Return x^n (mod p) // Assumes x, n >= 0, p>0, x<p, 0^0 = 1 // Overflow may occur if p > 31 bits // public static long power( long x, long n, long p ) { if (n == 0) return 1; long tmp = power( (x*x)%p, n/2, p ); if (n % 2 != 0) tmp = (tmp*x) % p; return tmp; }

Tong Wang UMass Boston CS 310 June 27, 2017 19 / 20

slide-20
SLIDE 20

GCD, Euclid’s Algorithm

gcd(a, b) ≡ gcd(a − b, b) gcd(a, b) ≡ gcd(b, a mod b) Assume n > m, gcd(n, m) = O(log n)

// Return the greatest common divisor public static long gcd( long a, long b ) { if (b == 0) return a; else return gcd( b, a % b); }

Tong Wang UMass Boston CS 310 June 27, 2017 20 / 20