Download presentation
Presentation is loading. Please wait.
Published byKory Sparks Modified over 9 years ago
1
Week 5 - Monday
2
What did we talk about last time? Linked list implementations Stacks Queues
4
Infix to Postfix Converter
6
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]; }
7
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]; }
8
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]);
10
Defining something in terms of itself To be useful, the definition must be based on progressively simpler definitions of the thing being defined
11
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
12
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
13
PHP PHP: Hypertext Processor ▪ (PHP: Hypertext Processor): Hypertext Processor ▪…▪… XINU XINU Is Not Unix ▪ (XINU Is Not Unix) Is Not Unix ▪…▪…
14
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
16
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
17
Problem 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
18
Base case (n 1): 1! = 0! = 1 Recursive case (n > 1): n! = n(n – 1)!
19
public static long factorial( int n ) { if( n <= 1 ) return 1; else return n*factorial( n – 1 ); } Base Case Recursive Case
20
Given an integer, count the number of zeroes in its representation Example: 13007804 3 zeroes
21
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
22
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
23
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
24
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.
25
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 ); else return search( array, n, start, midpoint ); } Base Cases Recursive Cases
26
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 = 2 x x = log 2 (n)
27
Pay no attention to the man behind the curtain…
28
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?
29
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: Push Pop
30
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 solve Call main solve factorial Call main solve Return
31
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 1202462 1
33
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
34
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
35
Base case (n = 1): Recursive case (n > 1):
36
public static int sum( int n ) { if( n == 1 ) return 1; else return n + sum( n – 1 ); } Base Case Recursive Case
37
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
38
The sequence: 1 1 2 3 5 8 13 21 34 55… Studied by Leonardo of Pisa to model the growth of rabbit populations
39
Find the n th term of the Fibonacci sequence Simple approach of summing two previous terms together Example: n = 7 1 1 2 3 5 8 13 1 2 3 4 5 6 7
40
Base cases (n = 1 and n = 2): Result = 1 Recursive case (n > 2): Result = fibonacci(n – 1) + fibonacci(n – 2)
41
public static int fib( int n ) { if( n <= 2 ) return 1; else return fib(n – 1) + fib(n – 2); } Base Case Recursive Case
42
Example: fib(6) fib(6) fib(4)fib(5)fib(4)fib(3) fib(2) fib(1) fib(2) fib(1)fib(3)fib(2) fib(1) Uh oh.
43
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(2 n/2 )
44
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
45
public static int fib2( int a, int b, int n ) { if( n <= 2 ) return b; else return fib2(b, a + b, n - 1); } //proxy method int fib( int n ) { return fib2(1, 1, n); } Base Case Recursive Case
46
We want to raise a number x to a power n, like so: x n We allow x to be real, but n must be an integer greater than or equal to 0 Example: (4.5) 13 = 310286355.9971923828125
47
Base case (n = 0): Result = 1 Recursive case (n > 0): Result = x ∙ x (n – 1)
48
public static double power( double x, int n ) { if( n == 0 ) return 1; else return x * power( x, n – 1); } Base Case Recursive Case
49
Each call reduces n by 1 n total calls What's the running time? O(n)
50
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 x n = x ∙ x (n – 1) But, it is also true that x n = x (n/2) ∙ x (n/2)
51
Assume that n is a power of 2 Base case (n = 1): Result = x Recursive case (n > 1): Result = (x (n/2) ) 2
52
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 Recursive Case
53
Each call reduces n by half log 2 (n) total calls Just like binary search Can we expand the algorithm to even and odd values of n?
54
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
55
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 Recursive Cases
58
Review for Exam 1
59
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
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.