Download presentation
Presentation is loading. Please wait.
Published bySybil Harvey Modified over 9 years ago
1
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Data Structures and Algorithms for Information Processing Some Notes on Recursion
2
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Recursion We’ve seen several examples of the use of recursion We’ll take a closer look at recursion as a style of programming Lends itself to analytical methods; proving program properties
3
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Verifying Program Properties How can we be sure that a program is correct? –Debug –Test cases –Make sure output matches another program –... None of these give absolute assurance
4
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Imperative Programming The “usual” style in Java, using commands Programs are written by create data (“state”) and storing it in variables Flow of control insures that correct sequence of assignments is executed
5
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Applicative Programming No references to other objects No side effects (assignments, output...) Some advantages: –Functions only return values –No need for loops –Easier to prove properties A different programming style, and a different way to think about programming
6
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Recursion l General pattern: recursive_fn(params) { if (…) return some_value; else... recursive_fn(new_params)... } l A recursive function call is made somewhere in the body of the function
7
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Tail Recursion l General pattern: tail_recursive_fn(params) { if (…) return some_value; else return tail_recursive_fn(new_params) } Tail recursive: the function does no work after the recursive call
8
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Tail Recursion l “Usual” recursive factorial // Precondition: n >= 0 static int fact1(int n) { if (n==0) return 1; else return n*fact1(n-1); }
9
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Tail Recursion Tail recursive factorial static int fact2(int n) { // Precondition: n >= 0 return fact2_aux(n, 1); } static int fact2_aux(int n, int accum) { if (n==0) return accum; else return fact2_aux(n-1, n*accum); }
10
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Execution Trace fact1(5) 5*fact1(4) 5*4*fact1(3) 5*4*3*fact1(2) 5*4*3*2*fact1(1) 5*4*3*2*1*fact1(0) 5*4*3*2*1*1 => 120
11
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Execution Trace fact2(5) fact2_aux(5,1) fact2_aux(4,5) fact2_aux(3,20) fact2_aux(2,60) fact2_aux(1,120) fact2_aux(0,120) => 120
12
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Example of Non-Tail Recursion // Precondition: y > 0 static int mult (int x, int y) { if (y==1) return x; else return x + mult(x, y-1); } Addition operation carried out after the recursive call
13
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Tail Recursion (cont) Tail recursive functions can be more efficient Often easier to prove properties of tail recursive functions –correctness, termination, cost –technique: induction
14
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Example: fact2 Want to prove using induction that fact2(n) => n! We do this by proving an appropriate property of the auxiliary function: fact2_aux(n, p) => n! * p
15
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Example: fact2 (cont) Base case: n=0 –for all p fact2_aux(0, p) => p = 0! * p Inductive step: n > 0: –Assume true for n-1 –For all p fact2_aux(n-1, p) =>(n-1)! * p
16
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Example: fact2 (cont) Inductive step: n > 0: –Assume true for n-1 –For all p fact2_aux(n-1, p) =>(n-1)! * p –So: fact2_aux(n, p) => fact2_aux(n-1, n*p) => (n-1)! * (n*p) = (n*(n-1)!)*p = n!*p
17
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Example: fact2 (cont) Proving termination by induction: –Base case: fact2_aux(0, p) => return p –Inductive case: terminates if operator * terminates
18
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Tail recursive reverse We can easily get an O(n) implementation using tail recursion: List rev2_aux(List x, List y) { if (x==null) return y; else return rev2_aux(x.next(), new List(x.value(), y)) } List reverse2(x) { return rev2_aux(x, null); }
19
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Cost of rev2_aux Let Cost[n,m] be the number of operations for rev2_aux(x,y) with x.length ()=n and y.length () = m Cost[0,m] = A (constant) n>0, Cost[n,m] = Cost[n-1,m+1] + B Thus, Cost[n,m] = A + nB = O(n)
20
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Fibonacci Numbers Want fib(0)=1, fib(1)=1, fib(n) = fib(n-1) + fib(n-2) if n>1 Simple recursive implementation: // Precondition: n>=0 i nt fib(int n) { if (n < 2) return 1; else return fib(n-1)+fib(n-2); }
21
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Fibonacci Numbers Cost is the same as the Fibonacci numbers themselves! fib(n) rises exponentially with n: –fib(n) > (1.618)^n / 2
22
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Imperative version int i=1; int a=1, b=1; while (i<n) { int c = a+b; // fib(i+1) a = b; b = c; i++; }
23
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Recursive Version Define an auxiliary function fib_aux Use two accumulator variables, one set to fib(i-1), the other to fib(i)
24
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Recursive Version int fib_aux (int n, int i, int x, int y) { if (i==n) return y; else return fib_aux(n, i+1, y, x+y); } int fib(int n) { if (n==0) return 1; else return fib_aux(n, 1, 1, 1); }
25
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Backtracking Search General pattern: Test if current position satisfies goal If not, mark current position as visited and make a recursive call to search procedure on neighboring points Exhaustive search, terminates as soon as goal is found
26
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Backtracking search: simple example The “bear game”: Start with initial number of bears Need to reach goal number within a certain number of step s Possible moves: –Add incr number of bears –If even divide current number in half Suppose initial=10, goal=100, incr=50,n=5
27
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Backtracking search: simple example Public static boolean bears (int initial, int goal, int incr, int n) { if (initial == goal) return true; else if (n==0) return false; else if (bears(initial+incr, goal, incr, n-1)) return true; else if (initial % 2 == 0) return bears(initial/2, goal, incr, n-1); else return false; }
28
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Backtracking search: simple example Why does this program terminate? What if we remove the restriction on the number of steps?
29
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. Some Notes on Recursion Benefits of Recursion Recursion can often be implemented efficiently Requires less work (programming and computation) Tail recursive versions require less stack space The code is typically much cleaner than imperative versions
Similar presentations
© 2024 SlidePlayer.com Inc.
All rights reserved.