CS 206 Introduction to Computer Science II 10 / 14 / 2009 Instructor: Michael Eckmann

Preview:

Citation preview

CS 206Introduction to Computer Science II

10 / 14 / 2009

Instructor: Michael Eckmann

Michael Eckmann - Skidmore College - CS 206 - Fall 2009

Today’s Topics• Comments/Questions?• Binary Search trees

–Discuss running time of delete–Allowing duplicate values

• General recursion ideas–Definition of recursion–Several examples

running time of delete• Last class we made a chart of the running times of common

operations done to sorted data stored in a linked list, array and

a BST. (Several of you were not here ...)

• Now that we've written delete in a BST what is the running

time?

Allowing duplicate values• One way to allow duplicate values in our BST, is --- if a key <

some key then it lives on the left side of it. If the key is >=

some key then it lives on the right side.

• Another way would be to change the BSTNode to contain a

count value which describes how many are in the tree.

• When you want to add a node with a key that already exists,

instead of inserting the new node, just ++ the count of that

node. To delete, decrement the count. When it gets to 0,

remove the node completely.

Allowing duplicate values• Assuming we implement it in the way that each node keeps

track of its count.

• How will this idea effect traversals?

• How about delete?

• Other concerns?

Recursion

• 1. have at least one base case that is not recursive• 2. recursive case(s) must progress towards the base case• 3. trust that your recursive call does what it says it will do

(without having to unravel all the recursion in your head.)• 4. try not to do redundant work. That is, in different

recursive calls, don't recalculate the same info.

Recursion

• some definitions are inherently recursive• e.g.• sum of the first n integers, n>= 1.• S(1) = 1• S(N) = S(N-1) + N

• recursive code for this• iterative code for this• simpler code for this (based on our proof) N*(N+1)/2• any problems with the recursive code? n=0 or large n?

Recursion

• The last example showed that recursion didn't really simplify our lives, but there are times when it does.

• e.g. If given an integer and you wanted to print the individual digits in order, but you didn't have the ability to easily convert an int >10 to a String.

• e.g. int n=35672;• If we wanted to print 3 first then 5 then 6 then 7 then 2,

we need to come up with a way to extract those digits via some mathematical computation.

• It's easy to get the last digit n%10 gives us that. • Notice: 35672 % 10 = 2 also 2 % 10 = 2.• Any ideas on a recursive way to display all the numbers in

order?

Recursion

void printDigits(int n){

if (n>=10)printDigits((n/10));

System.out.println( n%10 );}

// what's the base case here?

// what's the recursive step here? Will it always approach the base case?

Recursion

• Now that last problem was made up sort of, because Java (and most languages) allow us to print ints.

• However what if we wanted to print the int in a different base? Say base 2, 3, 4, 5, or some other base?

Recursion

• The fibonacci sequence is:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

– Can you detect the pattern?

Recursion

• The fibonacci sequence is:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

• Fibonacci numbers are simply defined recursively:F

0 = 0

F1 = 1

Fn = F

n-1 + F

n-2

• How could we convert this to code to calculate the ith fibonacci number?

Recursion• Fibonacci numbers are simply defined recursively:

F0 = 0

F1 = 1

Fn = F

n-1 + F

n-2

• How could we convert this to code to calculate the ith fibonacci number?int fib(int i){

if (i <= 1)return i;

elsereturn ( fib(i-1) + fib(i-2) );

}

Recursionint fib(int i){

if (i <= 1)return i;

elsereturn ( fib(i-1) + fib(i-2) );

}

Any problems with this code?

Recursionint fib(int i){

if (i <= 1)return i;

elsereturn ( fib(i-1) + fib(i-2) );

}

Any problems with this code?Yes – it makes too many calls. And further, these calls

are redundant.It violates that 4th idea of recursion stated earlier: in

different recursive calls, don't recalculate the same info.

Recursion• We know what a tree is.

• Can anyone give a recursive definition of a tree?

Recursion• We know what a tree is.

• Can anyone give a recursive definition of a tree?– A tree is empty or it has a root connected to 0 or more

subtrees.– (Note a subtree, taken on its own, is a tree.)

Recursion• Change making algorithms.

– Problem: have some amount of money for which you need to make change in the fewest coins possible.

– You have unlimited numbers of coins C1 ... C

N each

with different values.

• example: make change for .63 and the coins you have are C

1 =.01, C

2 =.05, C

3 =.10, and C

4 =.25 only.

• ideas?

Recursion• Change making algorithms.

– Problem: have some amount of money for which you need to make change in the fewest coins possible.

– You have unlimited numbers of coins C1 ... C

N each

with different values.

• example: make change for .63 and the coins you have are C

1 =.01, C

2 =.05, C

3 =.10, and C

4 =.25 only.

• The algorithm that works for these denominations is a greedy algorithm (that is, one that makes an optimal choice at each step to achieve the optimal solution to the whole problem.) Let's write it in Java.

Recursion• What if : make change for .63 and the coins you have are

C1 =.01, C

2 =.05, C

3 =.10, C

4 =.21 and C

5 =.25 only.

• A 21 cent piece comes into the picture.

Recursion• What if : make change for .63 and the coins you have are

C1 =.01, C

2 =.05, C

3 =.10, C

4 =.21 and C

5 =.25 only.

• A 21 cent piece comes into the picture.

• The greedy algorithm doesn't work in this case because the minimum is 3 coins all of C

4 =.21 whereas the greedy

algorithm would yield 2 .25's, 1 .10 and 3 .01's for a total of 6 coins.

• We always assume we have .01 coin to guarantee a way to make change.

Recursion• So, we want to create a way to solve the minimum # of

coins problem with arbitrary coin denominations.

• A recursive strategy is:– BASE CASE: If the change K, we're trying to make is

exactly equal to a coin denomination, then we only need 1 coin, which is the least # of coins.

– RECURSIVE STEP: Otherwise, for all possible values of i, split the amount of change K into two sets i and K-i.

• Solve these two sets recursively and when done with all the i's, keep the minimum sum of the number of coins among all the i's.

Recursion• split the total into parts and solve those parts recursively.

– e.g. – .63 = .01 + .62 – .63 = .02 + .61– .63 = .03 + .60– .63 = .04 + .59– .– .– .63 = .31 + .32– See example on page 288, figure 7.22– Each time through, save the least number of coins.

Recursion• split the total into parts and solve those parts recursively.

– e.g. – .63 = .01 + .62 – .63 = .02 + .61– .63 = .03 + .60– .63 = .04 + .59– .– .– .63 = .31 + .32– Each time through, save the least number of coins.– The base case of the recursion is when the change we

are making is equal to one of the coins – hence 1 coin.– Otherwise recurse.– Why is this bad?

Recommended