recursion - southern illinois university...

30
Recursion 1

Upload: others

Post on 27-Jun-2020

13 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

Recursion

1

Page 2: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

!! Solution given in terms of problem. Huh?

!! Each problem is a smaller instance of itself. !

! Implemented via functions. !

! Very powerful solving technique.

What is Recursion?

Page 3: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

!! Base case

– the point where the solution is known or obvious !!

! Recursive Step – Expressing the problem as a smaller instance of itself – How you get to the base case

Base Case and Recursive Step

Page 4: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

Binary Search

word: brave

aDictionary: A - Z open aDictionary in the middle

A - M search the left half: A - M

A - G search the left half: A - G

A - D search the left half: A - D

A - B search the left half: A - B

B search the right half: B

Base Case

Recursive step

Page 5: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

!search(in aDictionary:Dictionary, in word: string) if (aDictionary is one page in size)

Scan the page for the wordelse { Open aDictionary to a point near the middle Determine which half of aDictionary contains the word if (word is in the first half of aDictionary) search(first half of aDictionary, word) else search(second half of aDictionary, word) }

Binary Search

Base case: Assume we know how to scan a page for a word.

Recursive step: Note how in each instance we are solving a smaller version of the original problem.

Page 6: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

1.How can you define the problem in terms of a smaller problem of the same type?

!2.How does each recursive call diminish the size of the

problem?

!3.What instance of the problem can serve as the base

case?

!4.As the problem size diminishes, will you reach the base

case?

Four Questions

Page 7: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

factorial(n) = n.(n-1).(n-2)...1 n > 0factorial(0) = 1

!! observe that factorial(n-1) = (n-1).(n-2)...1 !! so factorial(n) = n.factorial(n-1) !! The solution to factorial(n) is now given in terms of factorial(n-1), a

similar problem, but smaller.

Factorial

Page 8: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

double Factorial(const int n) { // base case if (n == 0) { return (1); } else { // recursive step return ( n * Factorial(n - 1) ); } }

Code: Factorial

Page 9: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

1.Label each recursive step with a label, such as A, B,,,Z

!2.Keep a record of the current value of the

function's arguments. !

3.Keep a record of any local variable within the function.

Factorial Traced

Page 10: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

Factorial Traced

factorial(5) : n = 5 return (5 * factorial(4): A

factorial(2) : n = 2 return (2 * 1): A

factorial(3) : n = 3 return (3 * 2): A

factorial(4) : n = 4 return (4 * 6) : A

factorial(5) : n = 5 return (5 * 24)

factorial(4) : n = 4 return (4 * factorial(3): A

factorial(3) : n = 3 return (3 * factorial(2): A

factorial(2) : n = 2 return (2 * factorial(1): A

factorial(1) : n = 1 return (1 * factorial(0): A

factorial(0) : n = 0 return (1): A

factorial(1) : n = 1 return (1 * 1): A

if (n == 0) return (1); else return ( n * factorial(n - 1) ); // A

Page 11: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

Reverse String Display

H E L L O

O L L E H L L E HO

H E L L OFirst character first

H E L L OLast character first

rev(ello)•H o•rev(Hell)

Page 12: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

reverse(in s:string) if (string is empty)

do nothing else { reverse(s minus the first character) display first character in the string }

First Character First

String Outputcat att"" t ta tac

Page 13: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

reverse(in s:string) if (string is empty)

do nothing else { display last character in the string reverse(s minus the last character)}

Last Character First

String Outputcat tca ta c tac ""

Page 14: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

void DisplayString(string str) { uint len = str.length(); ! if (len != 0) { cout << str[len - 1]; DisplayString(str.substr(0, len – 1)); } }

Code: Reverse Display

Page 15: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

f(n) = f(n-1) + f(n-2) for n>2 f(2) = 1 f(1) = 1

!! The base case here is the value 1 for the first two fibonacci numbers. !!

! The recursive step is a combination of f(n-1) and f(n-2).

Fibonacci

Page 16: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

double Fib(const int n) { // base case if (n <= 2) { return (1); } else { // recursive step return ( Fib(n - 1) + Fib(n - 2) ); } }

Code: Fibonacci

Page 17: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

Fibonacci Traced

fib(6) = fib(5) + fib(4)

2

2 23

35

8

fib(5) = fib(4) + fib(3)

fib(4) = fib(3) + fib(2)

fib(3) = fib(2) + fib(1)

1 fib(2) = 1 1fib(1) = 1

fib(2) = 1 1

fib(3) = fib(2) + fib(1)

fib(2) = 11 fib(1) = 1 1

fib(4) = fib(3) + fib(2)

fib(3) = fib(2) + fib(1)

fib(2) = 11 fib(1) = 1 1

fib(2) = 1 1

Page 18: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

Find Min

2 1 4 5 0

2 1 4 5 0 min(2,1,4,5) <? 0

2 1 4 5 min(2,1,4) <? 5

2 1 4 min(2,1) <? 4

2 1 min(2) <?

2 min(2)

if (array has only one item) min(array) is that itemelse min(array) is the smallest of the first item and min(array minus first item)

Page 19: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

listType FindMin(const list ilist, const int len) { if (len == 1) { return (ilist[len - 1]); } else { listType cur = ilist[len - 1]; listType min = FindMin(ilist, len - 1); return ( (min < cur)? min : cur); } }

Code: FindMin

Page 20: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

binarySearch(in anArray:ArrayType, in value:ItemType) if (anArray is of size 1)

Determine if anArray's item is equal to valueelse { Find the midpoint of anArray Determine which half of anArray contains values if (value is in the first half of anArray) binarySearch(first half of anArray, value) else binarySearch(second half of anArray, value)}

Binary Search

Page 21: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

bool BinarySearch(const ilist list, const int first, const int last, const listType key, int& posFound) { int mid = (first + last) / 2; // base case if (last < first) { return (false); } else if (key == list[mid]) { posFound = mid; return (true); }

Code: BinarySearch

Page 22: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

else if (key < list[mid]) { // key in lower half return (BinarySearch(list, first, mid - 1, key, posFound)); } else { // key in upper half return (BinarySearch(list, mid + 1, last, key, posFound)); } }

Code: BinarySearch

Page 23: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

Binary Search Traced

binarySearch(-4, -2, -1, 3, 5, 6, 15, 21, 25): key = -1first:0 last:8 mid:4 arr[mid]:5 posFound:?

T

binarySearch(-4, -2, -1, 3): key = -1first:0 last:3 mid:1 arr[mid]:-2 posFound:?

binarySearch(-1, 3): key = -1first:2 last:3 mid:2 arr[mid]:-1 posFound:2

T

T

Page 24: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

Towers of Hanoi

!You have three poles and n disks. ! The disks are of different size with the largest at the bottom. !

! The challenge is to move all the disks, from a source pole to a destination pole, using the third pole as a holding place. !

! A disk of a larger size cannot be on top of a disk of a smaller size. !

! Assume towers(n, A, B, C) is our initial problem of moving n disks from the source pole, A, to the destination pole B, using pole C as a place holder.

!towers(n-1,A,C,B)towers(1,A,B,C)towers(n-1,C,B,A)

Page 25: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

void towers(const int n, const char source, const char destination, const char spare) { if (n == 1) { cout << "Move from " << source << " to " << destination << endl; } else { towers(n - 1, source, spare, destination); towers(1, source, destination, spare); towers(n - 1, spare, destination, source); } }

Code: Towers

Page 26: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

int image[16][16] = { {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1}, {1,1,1,1,1,1,1,0,0,1,0,1,1,1,1,1}, {1,1,1,1,1,1,0,1,1,1,1,0,1,1,1,1}, {1,1,1,1,0,0,1,1,1,1,1,1,0,1,1,1}, {1,1,0,0,1,1,1,1,1,1,1,1,1,0,0,1}, {1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0}, {0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0}, {0,1,1,1,1,1,1,1,1,0,0,1,1,1,0,1}, {0,1,1,1,0,1,1,1,0,1,1,0,1,1,0,1}, {0,1,1,0,1,0,1,1,0,1,1,1,0,0,1,1}, {1,0,0,1,1,0,1,1,0,1,1,1,1,0,1,1}, {1,0,1,1,1,0,1,0,1,1,1,1,1,1,1,1}, {1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1}, };

Code: FloodFill

Page 27: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

void DisplayImage(void); void FloodFill (int x, int y); bool Filled(int x, int y); void Color(int x, int y); !void main(void) { DisplayImage(); FloodFill(6, 6); DisplayImage(); } !void FloodFill (int x, int y) { if ( !Filled(x, y) ) { Color(x, y); FloodFill(x-1, y); // left FloodFill(x+1, y); // right FloodFill(x, y-1); // up FloodFill(x, y+1); // down } }

Code: FloodFill

Page 28: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

!!void DisplayImage(void) { for (int y = 0; y < 16; y++) { for (int x = 0; x < 16; x++) { cout << image[y][x]; } cout << endl; } cout << endl << endl; }

Code: FloodFill

Page 29: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

!!bool Filled(int x, int y) { bool isFilled = true; ! cout << "Checking: " << y << "," << x << endl; if (image[y][x] == 1) { isFilled = false; } return (isFilled); } !!void Color(int x, int y) { image[y][x] = 0; }

Code: FloodFill

Page 30: Recursion - Southern Illinois University Edwardsvillestornar/courses/notes/cs240/15.Recursion.pdfRecursion is very elegant, but can also be very inefficient.!! Recursion can be inefficient

! Recursion is very elegant, but can also be very inefficient. !

! Recursion can be inefficient for two reasons: ! The overhead associated with function calls. ! The inefficiency of the solution itself (see the fibonacci

example). !

! Basically, use recursion when there is no elegant iterative solution, and the recursive solution is not cost prohibitive.

Closing Remarks