Data Structures and Algorithms for Information Processing Some Notes on Recursion

Data Structures and
Algorithms for Information
Processing
Some Notes on Recursion
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
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
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
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
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
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
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
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
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
Recursion
 General pattern:
recursive_fn(params) {
if (…) return some_value;
else ... recursive_fn(new_params) ...
}
 A recursive function call is made
somewhere in the body of the function
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
Tail Recursion
 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
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
Tail Recursion
 “Usual” recursive factorial
// Precondition: n >= 0
static int fact1(int n) {
if (n==0) return 1;
else return n*fact1(n-1);
}
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
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);
}
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
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
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
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
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
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
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
Tail Recursion (cont)
• Tail recursive functions can be more
efficient
• Often easier to prove properties of tail
recursive functions
– correctness, termination, cost
– technique: induction
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
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
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
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
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
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
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
Example: fact2 (cont)
• Proving termination by induction:
– Base case:
fact2_aux(0, p) => return p
– Inductive case:
terminates if operator * terminates
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
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); }
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
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)
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
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
int fib(int n) {
if (n < 2) return 1;
else return fib(n-1)+fib(n-2);
}
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
Fibonacci Numbers
• Cost is the same as the Fibonacci
numbers themselves!
• fib(n) rises exponentially with n:
– fib(n) > (1.618)^n / 2
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
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++;
}
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
Recursive Version
• Define an auxiliary function fib_aux
• Use two accumulator variables, one set
to fib(i-1), the other to fib(i)
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
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);
}
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
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
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
Backtracking search:
simple example
The “bear game”:
• Start with initial number of bears
• Need to reach goal number within a certain
number of steps
• Possible moves:
– Add incr number of bears
– If even divide current number in half
• Suppose initial=10, goal=180, incr=50,n=5
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
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;
}
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
Backtracking search:
simple example
• Why does this program
terminate?
• What if we remove the restriction
on the number of steps?
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
General Backtracking
boolean solve(Configuration conf) {
if(no more choices) return (conf is goal)
for (each possible choice) {
make choice to conf
if(solve(conf)) return true
Try with:
N-Queens
unmake choice of conf
Sudoku
}
:
return false
Etc.
}
90-723: Data Structures
and Algorithms for
Information Processing
From Stanford Video on Program
Abstractions Lecture 11
Copyright © 1999, Carnegie Mellon. All Rights Reserved.
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
• Sometimes easier to prove program
properties
90-723: Data Structures
and Algorithms for
Information Processing
Some Notes on Recursion
Copyright © 1999, Carnegie Mellon. All Rights Reserved.