recursion ellen walker cpsc 201 data structures hiram college

Post on 17-Dec-2015

215 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Recursion

Ellen Walker

CPSC 201 Data Structures

Hiram College

Divide & Conquer

• To solve a big problem, break it down into smaller problems

• Examples:– Find the largest element in a list by comparing

pairs of elements– Binary search: find an element in a list by

deciding which half of the list it is in, and sorting the smaller half-list

Recursion

• Every smaller problem (except the smallest one) is an instance of the larger problem

• Examples:– Binary Search– Factorial– Fibonacci number

• Implementation: function that calls itself

Sequential Search as Recursion

//Find (the first instance of) element in list• If the list is empty, return “not found”• Else if the first element of the list is the one

you’re looking for, return it• Else search in the smaller list starting from

the second element of the list

Sequential Search in Java

//Check if value is in array of integers

//Note: end is one value beyond the last in list

boolean search1 (int value, int[] list, int st, int end){

if (st==end) return false; // empty list

if (list[st]==value) return true;

return search1(value, list, st+1, end);

}

Sequential Search as Divide & Conquer

• Divide the problem into two smaller problems:1. Is the value the first element of the list?

2. Find the value in the smaller list starting at the second element.

– Disadvantage: each “smaller” problem isn’t very much smaller

Binary Search

• Is the element in the first or second half of the list? (For a sorted list, this is a single comparison to the middle element)

• Search for the element in the appropriate half of the list

Binary Search in Java

boolean search2(int val, int[] list, int st, int end){

if (st==end) return false; //empty list

int middle = (end-st)/2;

if (list[middle]==val) return true;

if (val < list[middle]) return

search2(val,list,st,middle));

else return

search2(val, list, middle+1, end); }

Binary vs. Sequential

• Sequential search: each list search is 1 smaller

• Binary search: each list search is half as big

• Binary search is faster, but…• Binary search requires a sorted list

Aspects of A Recursive Solution

• Base case (or basis or degenerate case)– List is empty, List has 1 element

• Recursive call– Call to search1 or search2

• Recursive call must be “closer” to the base case– The list is shorter in the recursive call

4 Questions for Recursive Algorithm Design

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

• “single step” + “smaller problem”

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 this base case?

4 Answers for Factorial

1. How can you define the problem…Fact(N) is N*Fact(N-1)

2. How does each … call diminish…N-1 is smaller than N

3. What … can serve as the base case?Fact(0) is 1

4. …will you reach the base case? Yes, as long as you start with N≥0 (a precondition)

Factorial in Java

• Note: this is a “valued” recursive function• The final result is constructed from the results

of recursive calls

int Fact(int N){

assert (N>=0); //make sure of precondition

if (N==0) return 1;

else return N*Fact(N-1); }

Activation record

• Information recorded for each function call– Values of the parameters– Function’s local variables– Space for result– Where to return to (important if multiple calls!)

• For each function call, create a new activation record

• For each return, erase the activation record

Writing a string backward

• Base case:

• Define the problem in terms of a smaller one?

• How does each case diminish…?

• Guaranteed to reach the base case?

Multiple Calls in One Function

• Fibonacci sequence (counting rabbits)• Rabbit(N) = Rabbit(N-1)+Rabbit(N-2)• Rabbit(1) = Rabbit(2) = 1• (Rabbit is not defined for values < 1)

A Counting Problem

• How many ways to visit k of n planets?– Pick some planet (p)– There are count(n-1, k) ways to visit k planets

without visiting p– There are count(n-1, k-1) ways to visit k planets

with visiting p– Therefore: count(n, k) =

count(n-1,k)+count(n-1,k-1)– Base case?

Impractical Recursions

• Fibonacci: makes as many calls as rabbits!– Solution: compute it iteratively (save intermediate

steps)

• Counting: similar to Fibonacci – Solution: use mathematics to come up with a

closed form– Count(n,k) = n! / (k! (n-k)!)

Impractical but unavoidable

• Towers of Hanoi• Move N disks from one tower to another,

never putting a larger disk on a smaller disk• Solution in 3 steps:

– Recursively move N-1 disks to the extra tower– Move the Nth disk to the destination tower– Recursively move N-1 disks to the destination

tower

• Solution time: O(2N)

K’th smallest element

• Pick a “partition” element & put smaller elements before, and larger elements after– Remember quicksort?

• If “partition” element is k’th, it is the answer• Otherwise, recurse over the half that has the

k’th element in it (change k if it’s the second half!)

• Impossible to predict how long it will take without knowing the exact array!

Recursive Linked List

• The empty list is a linked list• A list consisting of a head item followed by a

list of the rest of the items is a linked list• Method to

– Add at the beginning of the list– Add at the end of the list

• Recursive method to – Count the elements– See if an element is in the list

top related