recursion - github pages

65
Recursion CS 2110: Software Development Methods April 8, 2019

Upload: others

Post on 25-Jan-2022

8 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Recursion - GitHub Pages

Recursion

CS 2110: Software Development MethodsApril 8, 2019

Page 2: Recursion - GitHub Pages

Given an 8× 8 board with one piece missing, tile with L-shapedtrominoes.

Interactive: http://goo.gl/npFQUD1

Page 3: Recursion - GitHub Pages

Concurrency and Locking

Reviewing Friday’s In-Class Activity

3

Page 4: Recursion - GitHub Pages

Recursion

https://www.xkcd.com/688/

4

Page 5: Recursion - GitHub Pages

Recursive Mindset

• Recursion breaks a difficult problem into one or more simplerversions of itself

5

Page 6: Recursion - GitHub Pages

Recursive Mindset

Remember Binary Search? Quickly turn to page 394 (without magic)

When do we stop? How would we formalize this in pseudocode? 6

Page 7: Recursion - GitHub Pages

Recursive Mindset

Recursive Binary Search: Quickly turn to page 394 (without magic)find(page_number,book):

page = flip to middleif page == page_number

return foundif page_number is before page

return find(page_number, first half)if page_number is after page

return find(page_number, second half)

7

Page 8: Recursion - GitHub Pages

Definition (Don’t Write This One Down!)

Recursion

8

Page 9: Recursion - GitHub Pages

Definition (Don’t Write This One Down!)

Recursion• see recursion.

8

Page 10: Recursion - GitHub Pages

Definition (Don’t Write This One Down!)

Recursion• see recursion.

8

Page 11: Recursion - GitHub Pages

Recursion

• Recursion breaks a difficult problem into one or more simplerversions of itself

• A definition is recursive if it is defined in terms of itself• Questions to ask yourself:

• How can we reduce the problem into smaller version of the sameproblem?

• How does each call make the problem smaller?• What is the base case?• Will we always reach the base case?

9

Page 12: Recursion - GitHub Pages

Example: Factorial

n!

• Solve by multiplying two numbers

10

Page 13: Recursion - GitHub Pages

Example: Factorial

n! = n× (n− 1)× (n− 2)× · · ·× 2× 1

• Solve by multiplying two numbers

10

Page 14: Recursion - GitHub Pages

Example: Factorial

n! = n× (n− 1)!

• Solve by multiplying two numbers

10

Page 15: Recursion - GitHub Pages

Example: Factorial

n! = n× (n− 1)!

• Solve by multiplying two numbers

10

Page 16: Recursion - GitHub Pages

Example: Factorial

n! = n× (n− 1)!

n (n− 1)!

n!

11

Page 17: Recursion - GitHub Pages

Example: Factorial

6 5!

6!

12

Page 18: Recursion - GitHub Pages

Example: Factorial

6

5 4!

6!

13

Page 19: Recursion - GitHub Pages

Example: Factorial

6!

6

5

4

3

2

1 0!

14

Page 20: Recursion - GitHub Pages

Definitions

Base caseThe case for which the solution can be stated nonrecursively

Recursive caseThe case for which the solution is expressed in terms of a smallerversion of itself

15

Page 21: Recursion - GitHub Pages

Definitions

Base caseThe case for which the solution can be stated nonrecursively

Recursive caseThe case for which the solution is expressed in terms of a smallerversion of itself

15

Page 22: Recursion - GitHub Pages

Example: Factorial

n! = n× (n− 1)!

• Base case:• Recursive case:

16

Page 23: Recursion - GitHub Pages

Example: Factorial

n! = n× (n− 1)!

• Base case: n = 0 ⇒ 0! = 1• Recursive case:

16

Page 24: Recursion - GitHub Pages

Example: Factorial

n! = n× (n− 1)!

• Base case: n = 0 ⇒ 0! = 1• Recursive case: n > 0 ⇒ n! = n× (n− 1)!

16

Page 25: Recursion - GitHub Pages

Example: Factorial

n! = n× (n− 1)!

• Base case: n = 0 ⇒ 0! = 1• Recursive case: n > 0 ⇒ n! = n× (n− 1)!

Advice: always put the base case first!

16

Page 26: Recursion - GitHub Pages

Translate to Code

Base case: n = 0 ⇒ 0! = 1

if (n == 0)return 1;

Magic box (recursive case): n! = n× (n− 1)!

return n * factorial(n-1);

17

Page 27: Recursion - GitHub Pages

Translate to Code

Base case: n = 0 ⇒ 0! = 1

if (n == 0)return 1;

Magic box (recursive case): n! = n× (n− 1)!

return n * factorial(n-1);

17

Page 28: Recursion - GitHub Pages

Translate to Code

Base case: n = 0 ⇒ 0! = 1

if (n == 0)return 1;

Magic box (recursive case): n! = n× (n− 1)!

return n * factorial(n-1);

17

Page 29: Recursion - GitHub Pages

Translate to Code

Base case: n = 0 ⇒ 0! = 1

if (n == 0)return 1;

Magic box (recursive case): n! = n× (n− 1)!

return n * factorial(n-1);

17

Page 30: Recursion - GitHub Pages

Translate to Code

public int factorial(int n) {// base case (always first)if (n == 0)

return 1;

// recursive casereturn n * factorial(n-1);

}

18

Page 31: Recursion - GitHub Pages

Recursion can be tricky!

Always need to stop at a base case

18

Page 32: Recursion - GitHub Pages

Translate to Code

public int factorial(int n) {// base case (always first)if (n == 0)

return 1;

// recursive casereturn n * factorial(n-1);

}

19

Page 33: Recursion - GitHub Pages

Translate to Code

public int factorial(int n) {// base case (always first)if (n <= 0)

return 1;

// recursive casereturn n * factorial(n-1);

}

20

Page 34: Recursion - GitHub Pages

Recursion vs. Iteration

Recursionpublic int factorial(int n) {

// base caseif (n <= 0)

return 1;

// recursive casereturn n * factorial(n-1);

}

Iteration

21

Page 35: Recursion - GitHub Pages

Recursion vs. Iteration

Recursionpublic int factorial(int n) {

// base caseif (n <= 0)

return 1;

// recursive casereturn n * factorial(n-1);

}

Iterationpublic int factorial(int n) {

int fact_n = 1;

for (int i = 1; i <= n; i++){fact_n = fact_n * i;

}return fact_n;

}

22

Page 36: Recursion - GitHub Pages

Recursion vs. Iteration

Recursionpublic int factorial(int n) {

// base caseif (n <= 0)

return 1;

// recursive casereturn n * factorial(n-1);

}

Build solution from top down

Iterationpublic int factorial(int n) {

int fact_n = 1;

for (int i = 1; i <= n; i++){fact_n = fact_n * i;

}return fact_n;

}

Build solution from bottom up

22

Page 37: Recursion - GitHub Pages

Views of Recursion

• Recursive definition: definition in terms of itself, such asn! = n× (n− 1)!

• Recursive procedure: a procedure that calls itselfex: factorial(int n)

• Recursive data structure: a data structure that contains apointer to an instance of itself:public class ListNode {

Object nodeItem;ListNode next, previous;...

}

23

Page 38: Recursion - GitHub Pages

Example: Fibonacci

1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, ...

• fib1 = 1• fib2 = 1• fibn = fibn−1 + fibn−2

24

Page 39: Recursion - GitHub Pages

Example: Fibonacci

1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, ...

• fib1 = 1• fib2 = 1• fibn = fibn−1 + fibn−2

24

Page 40: Recursion - GitHub Pages

Example: Fibonacci

1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, ...

• fib1 = 1• fib2 = 1• fibn = fibn−1 + fibn−2

Let’s formalize:

• Base case:• Recursive case:

24

Page 41: Recursion - GitHub Pages

Example: Fibonacci

1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, ...

• fib1 = 1• fib2 = 1• fibn = fibn−1 + fibn−2

Let’s formalize:

• Base case: n <= 2 ⇒ fibn = 1• Recursive case:

24

Page 42: Recursion - GitHub Pages

Example: Fibonacci

1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, ...

• fib1 = 1• fib2 = 1• fibn = fibn−1 + fibn−2

Let’s formalize:

• Base case: n <= 2 ⇒ fibn = 1• Recursive case: n > 2 ⇒ fibn = fibn−1 + fibn−2

24

Page 43: Recursion - GitHub Pages

Example: Fibonacci

1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, ...

• fib1 = 1• fib2 = 1• fibn = fibn−1 + fibn−2

Let’s formalize:

• Base case: n <= 2 ⇒ fibn = 1• Recursive case: n > 2 ⇒ fibn = fibn−1 + fibn−2

24

Page 44: Recursion - GitHub Pages

Translate to Code

Base case: n <= 2 ⇒ fibn = 1

if (n <= 2)return 1;

Recursive case: n > 2 ⇒ fibn = fibn−1 + fibn−2

return fibonacci(n-1) + fibonacci(n-2);

25

Page 45: Recursion - GitHub Pages

Translate to Code

Base case: n <= 2 ⇒ fibn = 1

if (n <= 2)return 1;

Recursive case: n > 2 ⇒ fibn = fibn−1 + fibn−2

return fibonacci(n-1) + fibonacci(n-2);

25

Page 46: Recursion - GitHub Pages

Translate to Code

Base case: n <= 2 ⇒ fibn = 1

if (n <= 2)return 1;

Recursive case: n > 2 ⇒ fibn = fibn−1 + fibn−2

return fibonacci(n-1) + fibonacci(n-2);

25

Page 47: Recursion - GitHub Pages

Translate to Code

Base case: n <= 2 ⇒ fibn = 1

if (n <= 2)return 1;

Recursive case: n > 2 ⇒ fibn = fibn−1 + fibn−2

return fibonacci(n-1) + fibonacci(n-2);

25

Page 48: Recursion - GitHub Pages

Translate to Code

public int fibonacci(int n) {// base case (always first)if (n <= 2)

return 1;

// recursive casereturn fibonacci(n-1) + fibonacci(n-2);

}

26

Page 49: Recursion - GitHub Pages

Recursion can be tricky!

It may not be the best solution.

26

Page 50: Recursion - GitHub Pages

Example: Fibonacci

27

Page 51: Recursion - GitHub Pages

Example: Fibonacci

28

Page 52: Recursion - GitHub Pages

Example: Fibonacci

Lots of redundant calculations! We should not repeat them!

28

Page 53: Recursion - GitHub Pages

Example: Fibonacci

Lots of redundant calculations! We should not repeat them! O(2n)

28

Page 54: Recursion - GitHub Pages

Example: Fibonacci

Lots of redundant calculations! We should not repeat them! O(2n)memoization: remember the things you’ve already calculated

28

Page 55: Recursion - GitHub Pages

Example: Iterative Fibonacci

public long fib(int n) {if ( n < 2 ) return 1; long answer;long prevFib=1, prev2Fib=1; // fib(0) & fib(1)for (int k = 2; k <= n; k++) {

answer = prevFib + prev2Fib;prev2Fib = prevFib;prevFib = answer;

}return answer;

}

29

Page 56: Recursion - GitHub Pages

Recursion vs. Iteration

• Any recursive solution may be written using iteration• Recursive algorithm may appear simpler, more intuitive

Recursion• “loop” is stopped by basecase

recurse(int i) {if (i < 1)

return;// do somethingrecurse(i-1);return;

}

Iteration• loop condition determineswhen to stop

while (i > 0) {// do somethingi--;

}

30

Page 57: Recursion - GitHub Pages

Recursion vs. Iteration

• Any recursive solution may be written using iteration• Recursive algorithm may appear simpler, more intuitive

Recursion• “loop” is stopped by basecase

recurse(int i) {if (i < 1)

return;// do somethingrecurse(i-1);return;

}

Iteration• loop condition determineswhen to stop

while (i > 0) {// do somethingi--;

}

30

Page 58: Recursion - GitHub Pages

Tromino Puzzle

Given an 8× 8 board with one piece missing, tile with L-shapedtrominoes.

Interactive: http://goo.gl/npFQUD31

Page 59: Recursion - GitHub Pages

Tromino Puzzle

Given an 8× 8 board with one piece missing, tile with L-shapedtrominoes.

Interactive: http://goo.gl/npFQUD31

Page 60: Recursion - GitHub Pages

Tromino Puzzle

Given an 8× 8 board with one piece missing, tile with L-shapedtrominoes.

Interactive: http://goo.gl/npFQUD31

Page 61: Recursion - GitHub Pages

Other Recursive Examples

• Towers of Hanoi• Euclid’s Algorithm• Fractals

32

Page 62: Recursion - GitHub Pages

Towers of Hanoi

The objective is to transfer entire tower A to the peg B, moving onlyone disk at a time and never moving a larger one onto a smallerone

• The algorithm to transfer n disks from A to B in general: Wefirst transfer n− 1 smallest disks to peg C, then move thelargest one to the peg B and finally transfer the n− 1 smallestback onto largest (peg B)

• The number of necessary moves to transfer n disks can befound by T(n) = 2n − 1

33

Page 63: Recursion - GitHub Pages

Euclid’s Algorithm

Calculating the greatest common divisor (gcd) of two positiveintegers is the largest integer that divides evenly into both of them

• E.g. greatest common divisor of 102 and 68 is 34 since both 102and 68 are multiples of 34, but no integer larger than 34divides evenly into 102 and 68

• Logic: If p > q, the gcd of p and q is the same as the gcd of qand p%q (where % is the remainder operator)

• Stop recursion once q becomes zero; at which point return p

34

Page 64: Recursion - GitHub Pages

Summary

• Recursion breaks a difficult problem into one or more simplerversions of itself

• Recursive definition: A definition in which something isdefined in terms of smaller versions of itself

• Recursive problem can be broken into two parts:• Base case: The case for which the solution can be statednonrecursively

• Recursive case: The case for which the solution is expressed in termsof a smaller version of itself

35

Page 65: Recursion - GitHub Pages

Summary

Recursion is tricky!

• Always put base case first• Base case should eventually happen given any input• Recursive solution may not always be the best

36