Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and...

41
Recursion CS 3358 – Data Structures

Transcript of Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and...

Page 1: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

Recursion

CS 3358 – Data Structures

Page 2: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

Big Picture

• Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount of effort.

• We will put some faith in the principles of mathematical induction as we write the program

• We will then check the program with a small, non-trivial example

• Anything that can be done with a loop, you can do recursively, but it’s certainly not appropriate in many cases.– Does it cause more or less work?

Page 3: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

What is recursion?

• Sometimes, the best way to solve a problem is by solving a smaller versionsmaller version of the exact same problem first

• Recursion is a technique that solves a problem by solving a smaller problemsmaller problem of the same type

Page 4: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

When you turn this into a program, you end up with functions that call themselves (recursive

functions)

int f(int x){ int y;  if(x==0) return 1; else { y = 2 * f(x-1); return y+1; }}

Page 5: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

All Odd Numbers are Prime

• How a physicist determines that all odd numbers are prime– 3, 5, 7 are all prime, 9 – experimental error, 11,

13 are prime… they must all be prime

• How a business major determines that all odd numbers are prime– 3, 5, 7, 9, 11, are all prime – they must all be

prime.

Page 6: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

The Danger With Testing

• It takes a long time to test a recursive program, and it’s easy to make mistakes along the way

//This code doesn’t work!!bool isPrime(int x) {if (x == 3) {

return true; }else if (isPrime(x-2)) {

return true; } else {

return false;}

}

Page 7: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

Problems defined recursively

• There are many problems whose solution can be defined recursively

Example: n! (n factorial)

1 if n = 0n!= (recursive solution)

(n-1)!*n if n > 0

1 if n = 0n!= (closed form solution)

1*2*3*…*(n-1)*n if n > 0

Page 8: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

Coding the factorial function

• Recursive implementation

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

Page 9: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.
Page 10: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

Coding the factorial function (cont.)

• Iterative implementation

int Factorial(int n) { int fact = 1;  for(int count = 2; count <= n; count++) fact = fact * count;  return fact;}

Page 11: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

Divide and Conquer

• Recursion works because mathematical induction works. Have faith. Or….

• Imagine that I have lots of very similar functionsint fact(int n) { if (n < 2) { return 1; } else { return n * fact2(n-1); }}int fact2(int n) {if (n < 2) { return 1; }

else { return n * fact3(n-1); }}// etc, etc.

Page 12: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

The Machine is Dumb

• The computer does not realize that the function is calling itself!– The computer cannot distinguish between fact calling

fact, and fact calling fact2

– After all, the machine code for fact and the machine code for fact2 are identical

• So, if we could just become as dumb as the computer, recursion would not be confusing.

Page 13: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

How is recursion implemented?

• What happens when a function gets called?

int a(int w){

return w+w;} 

int b(int x){

int z,y; ……………… // other statements

z = a(x) + y;

return z;}

Page 14: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

What happens when a function is called? (cont.)

• An activation record is stored into a stack (run-time stack)

1) The computer has to stop executing function b and starts executing function a

2) Since it needs to come back to function b later, it needs to store everything about function b that is going to need (x, y, z, and the place to start executing upon return)

3) Then, x from a is bounded to w from b4) Control is transferred to function a

Page 15: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

• After function a is executed, the activation record is popped out of the run-time stack

• All the old values of the parameters and variables in function b are restored and the return value of function a replaces a(x) in the assignment statement

What happens when a function is called? (cont.)

Page 16: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

What happens when a recursive function is called?

• Except the fact that the calling and called functions have the same name, there is really no difference between recursive and nonrecursive calls

int f(int x){

int y; 

if(x==0) return 1; else { y = 2 * f(x-1); return y+1; }}

Page 17: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

=f(3)

=f(2)

=f(1)

2*f(2)

2*f(1)

2*f(1)

=f(0)

Page 18: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

Another example: n choose k (combinations)

• Given n things, how many different sets of size k can be chosen?

n n-1 n-1 = + , 1 < k < n (recursive solution)k k k-1

n n! = , 1 < k < n (closed-form solution)k k!(n-k)!

with base cases:

n n = n (k = 1), = 1 (k = n) 1 n

Page 19: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

int Combinations(int n, int k)

{

if(k == 1) // base case 1

return n;

else if (n == k) // base case 2

return 1;

else

return(Combinations(n-1, k) + Combinations(n-1, k-1));

}

n choose k (combinations)

Page 20: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.
Page 21: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

Recursion vs. iteration

• Iteration can be used in place of recursion– An iterative algorithm uses a looping construct– A recursive algorithm uses a branching structure

• Recursive solutions are often less efficient, in terms of both time and space, than iterative solutions

• Recursion can simplify the solution of a problem, often resulting in shorter, more easily understood source code

Page 22: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

Termination, Stack Depth and Efficiency

• We should always check to ensure our recursive programs terminate.

• We should avoid programs that have lots of activation records on the stack at the same time (the stack depth)

• The time required for most recursive programs is proportional to the number of recursive calls

Page 23: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

How do I write a recursive function?

• Determine the size factor

• Determine the base case(s) (the one for which you know the answer)

• Determine the general case(s) (the one where the problem is expressed as a smaller version of itself)

• Verify the algorithm (use the "Three-Question-Method")

Page 24: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

Three-Question Verification Method 1. The Base-Case Question:

Is there a nonrecursive way out of the function, and does the routine work correctly for this "base" case? 

2. The Smaller-Caller Question:Does each recursive call to the function involve a smaller case of the original problem, leading inescapably to the base case? 

3. The General-Case Question:Assuming that the recursive call(s) work correctly, does the whole function work correctly?

Page 25: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

Step 1: Identify Your “Base Case”

• A base case is an input value (or set of values) for which:– Determining the result of our function is

trivially easy– All other values can ultimately be reduced to

(one of) our base case(s) through a finite sequence of “decompositions”

Page 26: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

Base Case Examples

• Factorial and Fibonacci: n < 2

• Sorting: n < 2 (either array has 1 element or it has no elements at all)

• Towers of Hanoi: n == 1 (exactly one ring)

• Making Change: The amount of change is exactly the same monetary value as a single coin

Page 27: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

Step 2: Pick a Decomposition

• It may take us a couple of tries to get the decomposition right, but we have to start somewhere

• The decomposition must:– Reduce the problem to a “smaller problem”

– Result in eventually reaching the base case

– Somehow be useful to solving the original problem

Page 28: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

Example Decompositions

• Subtract one from n (and compute n-1 factorial)

• Divide the array in half (and sort each half)

• Skip the first number (and compute the mean of the remaining elements)???

Page 29: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

Recursive binary search • Non-recursive implementation

template<class ItemType>void SortedType<ItemType>::RetrieveItem(ItemType& item, bool& found){ int midPoint; int first = 0; int last = length - 1; found = false; while( (first <= last) && !found) { midPoint = (first + last) / 2; if (item < info[midPoint]) last = midPoint - 1; else if(item > info[midPoint]) first = midPoint + 1; else { found = true; item = info[midPoint]; } }}

Page 30: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

• What is the size factor?The number of elements in (info[first] ... info[last])

• What is the base case(s)? (1) If first > last, return false (2) If item==info[midPoint], return true

• What is the general case?if item < info[midPoint] search the first halfif item > info[midPoint], search the second half

Recursive binary search (cont’d)

Page 31: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

template<class ItemType>bool BinarySearch(ItemType info[], ItemType& item, int first, int last){ int midPoint; 

if(first > last) // base case 1 return false; else { midPoint = (first + last)/2; if(item < info[midPoint]) return BinarySearch(info, item, first, midPoint-1); else if (item == info[midPoint]) { // base case 2 item = info[midPoint]; return true; } else return BinarySearch(info, item, midPoint+1, last); }}

Recursive binary search (cont’d)

Page 32: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

template<class ItemType>void SortedType<ItemType>::RetrieveItem

(ItemType& item, bool& found)

{

found = BinarySearch(info, item, 0, length-1);

}

Recursive binary search (cont’d)

Page 33: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

Recursive InsertItem (sorted list)

location

location

location

location

Page 34: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

• What is the size factor?The number of elements in the current list

What is the base case(s)?1) If the list is empty, insert item into the empty list2) If item < location->info, insert item as the first

node in the current list

• What is the general case?Insert(location->next, item)

Recursive InsertItem (sorted list)

Page 35: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

template <class ItemType>void Insert(NodeType<ItemType>* &location, ItemType item){ if(location == NULL) || (item < location->info)) { // base cases NodeType<ItemType>* tempPtr = location; location = new NodeType<ItemType>; location->info = item; location->next = tempPtr; } else Insert(location->next, newItem); // general case} template <class ItemType>void SortedType<ItemType>::InsertItem(ItemType newItem){ Insert(listData, newItem);}

Recursive InsertItem (sorted list)

Page 36: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

- No "predLoc" pointer is needed for insertionlocation

Page 37: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

Recursive DeleteItem (sorted list)

location

location

Page 38: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

• What is the size factor?The number of elements in the list

• What is the base case(s)? If item == location->info, delete node pointed by location

• What is the general case? Delete(location->next, item)

Recursive DeleteItem (sorted list)

(cont.)

Page 39: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

template <class ItemType>void Delete(NodeType<ItemType>* &location, ItemType item){ if(item == location->info)) { NodeType<ItemType>* tempPtr = location; location = location->next; delete tempPtr; } else Delete(location->next, item);} template <class ItemType>void SortedType<ItemType>::DeleteItem(ItemType item){ Delete(listData, item);}

Recursive DeleteItem (sorted list)

(cont.)

Page 40: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

Recursion can be very inefficient is some cases

+=

=

=

=

=

=

+ +

+ + + +

++ + + + +

+

+

+

+

+ + +

+ + + + + + +

+ +

+

++++++++3

3

C om b (3 , 1 )

2

C om b (2 , 1 )

1

C om b (2 , 2 )

C om b (3 , 2 )

C om b (4 ,2 )

2

C om b (2 , 1 )

1

C om b (2 , 2 )

C om b (3 , 2 )

1

1

C om b (3 , 3 )

C om b (4 , 3 )

C om b (5 , 3 )

2

C om b (2 , 1 )

1

C om b (2 , 2 )

C om b (3 , 2 )

1

1

C om b (3 , 3 )

C om b (4 , 3 )

1

1

1

C om b (4 , 4 )

C om b (5 , 4 )

C om b (6 ,4 )

15

Page 41: Recursion CS 3358 – Data Structures. Big Picture Our objective is to write a recursive program and convince ourselves it is correct with the minimum amount.

Deciding whether to use a recursive solution

• When the depth of recursive calls is relatively "shallow"

• The recursive version does about the same amount of work as the nonrecursive version

• The recursive version is shorter and simpler than the nonrecursive solution