Week 5 - Monday. What did we talk about last time? Linked list implementations Stacks Queues.

59
CS221 Week 5 - Monday

Transcript of Week 5 - Monday. What did we talk about last time? Linked list implementations Stacks Queues.

Page 1: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

CS221Week 5 - Monday

Page 2: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Last time

What did we talk about last time? Linked list implementations

Stacks Queues

Page 3: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Questions?

Page 4: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Infix to Postfix Converter

Project 2

Page 5: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Assignment 2 Post-Mortem

Page 6: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Project 1 loops

For some reason, people like to have crazy loops:

For this (relatively simple) case, it's not terrible, but the more complex it gets, the harder it is to think about indexes that jump around

Even so, what do i and j mean in this case?

for( int i = 0; i < height; ++i )for( int j = 0; j < width*3; j += 3 ) {

data[i][j] = 255 – data[i][j]);data[i][j + 1] = 255 – data[i][j + 1];data[i][j + 2] = 255 – data[i][j + 2];

}

Page 7: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Project 1 loops continued I like to keep my for loop indexes simple,

because loops are hard to thinking about Written this way, my indexes are rows and

columns:for( int row = 0; row < height; ++row )

for( int column = 0; column < width; ++column ) {data[row][3*column] =

255 – data[row][3*column]);data[row][3*column + 1] =

255 – [row][3*column + 1];data[row][3*column + 2] =

255 – [row][3*column + 2];}

Page 8: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Project 1 loops continued

Or even better:

I don't object to i and j, but a loop index should mean something

for( int row = 0; row < height; ++row )for( int column = 0; column < width; ++column )

for( int color = 0; color < 3; ++color )data[row][3*column + color] = 255 – data[row][3*column + color]);

Page 9: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Recursion

Page 10: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

What is Recursion?

Defining something in terms of itself

To be useful, the definition must be based on progressively simpler definitions of the thing being defined

Page 11: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Bottom Up

It is possible to define something recursively from the bottom up

We start with a simple pattern and repeat the pattern, using a copy of the pattern for each part of the starting pattern

Page 12: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Top Down

Explicitly: n! = (n)(n – 1)(n – 2) … (2)(1)Recursively: n! = (n)(n – 1)! 6! = 6 ∙ 5!

5! = 5 ∙ 4!▪ 4! = 4 ∙ 3!▪ 3! = 3 ∙ 2!

2! = 2 ∙ 1! 1! = 1

6! = 6 ∙ 5 ∙ 4 ∙ 3 ∙ 2 ∙ 1 = 720

Page 13: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Examples in Acronyms

PHP PHP: Hypertext Processor▪ (PHP: Hypertext Processor): Hypertext

Processor▪ …

XINU XINU Is Not Unix▪ (XINU Is Not Unix) Is Not Unix▪ …

Page 14: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Useful Recursion

Two parts: Base case(s)

Tells recursion when to stop For factorial, n = 1 or n = 0 are

examples of base cases Recursive case(s)

Allows recursion to progress "Leap of faith" For factorial, n > 1 is the recursive case

Page 15: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Solving Problems with Recursion

Page 16: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Approach for Problems

Top down approach Don’t try to solve the whole problem Deal with the next step in the

problem Then make the "leap of faith" Assume that you can solve any

smaller part of the problem

Page 17: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Problem

ProblemProblemProblem

Walking to the Door

Problem: You want to walk to the door

Base case (if you reach the door): You’re done!

Recursive case (if you aren’t there yet): Take a step toward the door

Problem

Page 18: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Implementing Factorial

Base case (n 1): 1! = 0! = 1

Recursive case (n > 1): n! = n(n – 1)!

Page 19: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Code for Factorial

public static long factorial( int n ){if( n <= 1 )

return 1;else

return n*factorial( n – 1 );}

Base Case

RecursiveCase

Page 20: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Count the Zeroes

Given an integer, count the number of zeroes in its representation

Example: 13007804 3 zeroes

Page 21: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Recursion for Zeroes

Base cases (number less than 10): 1 zero if it is 0 No zeroes otherwise

Recursive cases (number greater than or equal to 10): One more zero than the rest of the

number if the last digit is 0 The same number of zeroes as the rest

of the number if the last digit is not 0

Page 22: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Code for Zeroes

public static int zeroes( int n ){if( n == 0 )

return 1;else if( n < 10 )

return 0;else if( n % 10 == 0 )

return 1 + zeroes( n / 10 );else

return zeroes( n / 10 );}

Base Cases Recursive

Cases

Page 23: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Searching in a Sorted Array

Given an array of integers in (ascending) sorted order, find the index of the one you are looking for

Useful problem with practical applications

Recursion makes an efficient solution obvious

Play the High-Low game

Page 24: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Recursion for Binary Search Base cases:

The number in the middle of the range is the one you are looking for. Return its index.

The number isn’t in the range you are looking at. Return -1.

Recursion cases: The number in middle of the range is too

high. Look in the range below it. The number in the middle of the range is too

low. Look in the range above it.

Page 25: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Code for Binary Search

public static int search( int[] array, int n, int start, int end )

{int midpoint = (start + end)/2;if( array[midpoint] == n )

return midpoint;else if( start >= end )

return -1;else if( array[midpoint] < n )

return search( array, n, midpoint + 1, end );

elsereturn search( array, n, start,

midpoint );}

BaseCases

RecursiveCases

Page 26: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Time for Binary Search

Each recursive call splits the range in half In the worst case, we will have to keep

splitting the range in half until we have a single number left

We want to find the number of times that we have to multiply n by ½ before we get 1 n(½)x = 1 n = 2x

x = log2(n)

Page 27: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

How Does it Work Inside The Computer?Pay no attention to the man behind the curtain…

Page 28: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

All this math is great, but…

How does it actually work inside a computer?

Is there a problem with calling a function inside the same function?

How does the computer keep track of which function is which?

Page 29: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

The Stack

As you know, a stack is a FILO data structure used to store and retrieve items in a particular order

Just like a stack of blocks:

A A

BPush

A

B

CPush

A

BPop

Page 30: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Stack for Functions

In the same way, the local variables for each function are stored on the stack

When a function is called, a copy of that function is pushed onto the stack

When a function returns, that copy of the function pops off the stack

main main

solve

Call

main

solve

factorial

Call

main

solve

Return

Page 31: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Example with Factorial

Each copy of factorial has a value of n stored as a local variable

For 6! :

6*factorial(5)

5*factorial(4)

4*factorial(3)

3*factorial(2)

2*factorial(1)

1

x = factorial(6);factorial(6)

factorial(5)

factorial(4)

factorial(3)

factorial(2)

factorial(1)

720

120

24

6

2

1

Page 32: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Issues of Efficiency

Page 33: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

When to use recursion?

Recursion is a great technique One of its strengths is in writing

concise code to solve a problem Some recursive solutions are very

efficient Some are not It pays to be aware of both

Page 34: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Summation

Find the sum of the integers 1 through n

Example: n = 8 sum(8) = 8 + 7 + 6 + 5 + 4 + 3 + 2

+ 1 sum(8) = 36

Page 35: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Recursion for Summing

Base case (n = 1):

Recursive case (n > 1):

1

1

1i

i

1

11

n

i

n

i

ini

Page 36: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Code for Summing

public static int sum( int n ){if( n == 1 )

return 1;else

return n + sum( n – 1 );}

Base Case

RecursiveCase

Page 37: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Why not recursion?

Recursive summing takes linear time (summing n takes n function calls)

Is there another way to find this sum?

Closed form equation

Constant time! Remember the story of young Gauss

n

i

nni

1 2)1(

Page 38: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Fibonacci

The sequence: 1 1 2 3 5 8 13 21 34 55… Studied by Leonardo of Pisa to model the

growth of rabbit populations

Page 39: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Fibonacci Problem

Find the nth term of the Fibonacci sequence

Simple approach of summing two previous terms together

Example: n = 71 1 2 3 5 8 131 2 3 4 5 6 7

Page 40: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Recursion for Fibonacci

Base cases (n = 1 and n = 2): Result = 1

Recursive case (n > 2): Result = fibonacci(n – 1) + fibonacci(n –

2)

Page 41: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Code for Fibonacci

public static int fib( int n ){if( n <= 2 )

return 1;else

return fib(n – 1) + fib(n – 2);

}

Base Case

RecursiveCase

Page 42: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

What’s the running time for fib()?

Example: fib(6) fib(6)

fib(4)fib(5)

fib(4) fib(3)

fib(3) fib(2) fib(2) fib(1)

fib(2) fib(1)

fib(3) fib(2)

fib(2) fib(1)

Uh oh.

Page 43: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Exponential Time for fib

For most cases, calling fib() makes calls two more calls to fib(), which each make two more calls to fib(), and so on…

Many values are redundantly computed

The final running time is O(2n/2)

Page 44: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Can we do better?

The recursion is fine from a mathematical perspective

We just need to avoid recomputing lower terms in the sequence

We can use the idea of carrying along both the (n – 1) term and the (n – 2) term in each recursive step

Page 45: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Code for Better Fibonacci

public static int fib2( int a, int b, int n )

{if( n <= 2 )

return b;else

return fib2(b, a + b, n - 1);}

//proxy methodint fib( int n ){return fib2(1, 1, n);

}

Base Case

RecursiveCase

Page 46: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Exponentiation

We want to raise a number x to a power n, like so: xn

We allow x to be real, but n must be an integer greater than or equal to 0

Example: (4.5)13 = 310286355.9971923828125

Page 47: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Recursion for Exponentiation

Base case (n = 0): Result = 1

Recursive case (n > 0): Result = x ∙ x(n – 1)

Page 48: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Code for Exponentiation

public static double power( double x, int n )

{if( n == 0 )

return 1;else

return x * power( x, n – 1);}

Base Case

RecursiveCase

Page 49: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Running time for power

Each call reduces n by 1n total calls What's the running time?

O(n)

Page 50: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Can we do better?

We need to structure the recursion differently

Instead of reducing n by 1 each time, can we reduce it by a lot more?

It’s true that xn = x ∙ x(n – 1)

But, it is also true that xn = x(n/2) ∙ x(n/2)

Page 51: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

New Recursion for Exponentiation

Assume that n is a power of 2 Base case (n = 1):

Result = x Recursive case (n > 1):

Result = (x(n/2))2

Page 52: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Code for Better Exponentiation

public static double power2( double x, int n )

{double temp;if( n == 1 )

return x;else{

temp = power2( x, n/2 );return temp * temp;

}}

Base Case

RecursiveCase

Page 53: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Running time for power2

Each call reduces n by half log2(n) total calls Just like binary search Can we expand the algorithm to

even and odd values of n?

Page 54: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Even Newer Recursion for Exponentiation

Base case (n = 1): Result = x

Recursive cases (n > 1): If n is even, result = (x(n/2))2

If n is odd, result = x ∙ (x((n – 1)/2))2

Page 55: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Code for Even Better Exponentiation

public static double power3( double x, int n ){double temp;if( n == 1 )

return x;else if( n % 2 == 0 ){

temp = power3( x, n/2 );return temp * temp;

}else{

temp = power3( x, (n – 1)/2 );return x * temp * temp;

}}

Base Case

RecursiveCases

Page 56: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Running time for power3

Each call reduces n by half (more or less) O(log2 n) total calls Does as well as power2() Better yet, we can use this solution to get

a logarithmic time answer for Fibonacci!

The nth term of the Fibonacci sequence is:

Where

Page 57: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Upcoming

Page 58: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Next time…

Review for Exam 1

Page 59: Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.

Reminders

Study for Exam 1 This Friday, September 25, in class

Start working on Project 2 Sign up for new teams on Canvas

immediately! You can't partner with someone you've

partnered with before I will start docking points if you haven't

picked your teams by Friday