Upload
ruby-craig
View
223
Download
0
Embed Size (px)
Citation preview
5
What is recursion?
ADS2 lecture 6
It is something defined in terms of itself
… but it must have a stopping condition!
… it must “bottom out”
7
Recursive functions
A recursive function is one that calls itself.
E.g. to calculate N! = N (N-1) (N-2) . . . 1, do the following:
if N = 0 then 1 else N (N-1)!
We have defined the factorial function ! In terms of itself.– Note the factorial function is applied to a smaller number
every time until it is applied to 0.
ADS2 lecture 6
The factorial function in Java
fact(4) = 4 * fact(3) = 4 * 3 * fact(2) = 4 * 3 * 2 * fact(1) = 4 * 3 * 2 * 1 * fact(0)
The factorial function in Java
fact(4) = 4 * fact(3) = 4 * 3 * fact(2) = 4 * 3 * 2 * fact(1) = 4 * 3 * 2 * 1 * fact(0) = 4 * 3 * 2 * 1 * 1
The factorial function in Java
fact(4) = 4 * fact(3) = 4 * 3 * fact(2) = 4 * 3 * 2 * fact(1) = 4 * 3 * 2 * 1 * fact(0) = 4 * 3 * 2 * 1 * 1 = 4 * 3 * 2 * 1
The factorial function in Java
fact(4) = 4 * fact(3) = 4 * 3 * fact(2) = 4 * 3 * 2 * fact(1) = 4 * 3 * 2 * 1 * fact(0) = 4 * 3 * 2 * 1 * 1 = 4 * 3 * 2 * 1 = 4 * 3 * 2
The factorial function in Java
fact(4) = 4 * fact(3) = 4 * 3 * fact(2) = 4 * 3 * 2 * fact(1) = 4 * 3 * 2 * 1 * fact(0) = 4 * 3 * 2 * 1 * 1 = 4 * 3 * 2 * 1 = 4 * 3 * 2 = 4 * 6
The factorial function in Java
fact(4) = 4 * fact(3) = 4 * 3 * fact(2) = 4 * 3 * 2 * fact(1) = 4 * 3 * 2 * 1 * fact(0) = 4 * 3 * 2 * 1 * 1 = 4 * 3 * 2 * 1 = 4 * 3 * 2 = 4 * 6 = 24
19
In general…
A recursive function when calling itself makes a clone and calls the clone with appropriate parameters.
Important: a workable recursive algorithm (function/procedure) must always:
• Rule 1: reduce size of data set, or the number its working on, each time
it is recursively called and
• Rule 2: provide a stopping case (terminating condition)
• Can always replace recursive algorithm with an iterative one, but often recursive solution much sleeker
• Factorial function is only simple example, but recursion is valuable tool in more complex algorithms.
ADS2 lecture 6
Linear recursion
20
With linear recursion a method is defined so that it makes at most one recursive call each time it is invoked.Useful when we view an algorithmic problem in terms of a first and/or last element plus a remaining set with same structure as original set.
Example 1 : factorial exampleExample 2: summing the elements of an array -
Algorithm LinearSum(A,n): Input: An integer array A and integer n1, such that A has at least n elements Output:The sum of the first n integers in A if n=1 then return A[0] else return LinearSum(A,n-1)+A[n-1]
This is pseudocode. Used in GoTa a lot.
ADS2 lecture 6
21
Visualizing Recursion
• Recursion trace• A box for each recursive call• An arrow from each caller to
callee• An arrow from each callee to
caller showing return value
Example recursion trace:
RecursiveFactorial(4)
RecursiveFactorial(3)
RecursiveFactorial(2)
RecursiveFactorial(1)
RecursiveFactorial(0)
return 1
call
call
call
call
return 1*1 = 1
return 2*1 = 2
return 3*2 = 6
return 4*6 = 24 final answercall
ADS2 lecture 6
Actually we will remove the blue arrows on the right, to make it simpler
Example 3: RaisePower
Algorithm RaisePower(m,n): Input: Integers m,n Output: value of mn
if n=0 then return 1 else return (m*RaisePower(m,n-1))
1
.0
1
m
mmm nn
Example 3: RaisePower
Algorithm RaisePower(m,n): Input: Integers m,n Output: value of mn
if n=0 then return 1 else return (m*RaisePower(m,n-1))
1
.0
1
m
mmm nn
Does RaisePower satisfy rules 1 and 2? Yes!
Example 3: RaisePower
Algorithm RaisePower(m,n): Input: Integers m,n Output: value of mn
if n=0 then return 1 else return (m*RaisePower(m,n-1))
1
.0
1
m
mmm nn
Does RaisePower satisfy rules 1 and 2? Yes!
Rule 1 (number function working on is decreased)
Example 3: RaisePower
Algorithm RaisePower(m,n): Input: Integers m,n Output: value of mn
if n=0 then return 1 else return (m*RaisePower(m,n-1))
1
.0
1
m
mmm nn
Does RaisePower satisfy rules 1 and 2? Yes!
Rule 1 (number function working on is decreased)
Rule 2 ( stopping case)
ADS2 lecture 6 29
Recursion trace, m=2, n=4
RaisePower(2,4)
return 1
return 2*1=2
return 2*8=16 final answercall
call
call
call
call
RaisePower(2,3)
RaisePower(2,2)
RaisePower(2,1)
RaisePower(2,0)
return 2*2=4
return 2*4=8
And in Java…
30
public static int raisePower(int m, int n){ if (n==0) return 1; else return(m*raisePower(m,n-1));}
ADS2 lecture 6
33
Algorithm Has9(n): Input: Integer n Output: whether 9 appears in decimal expansion of n if (n mod 10)=9 then return true else if (n<10) then return false else return Has9(n/10)
ADS2 lecture 6
has9
34
Does Has9 satisfy rules 1 and 2? Yes!
Algorithm Has9(n): Input: Integer n Output: whether 9 appears in decimal expansion of n if (n mod 10)=9 then return true else if (n<10) then return false else return Has9(n/10)
ADS2 lecture 6
has9
35
Does Has9 satisfy rules 1 and 2? Yes!
Rule 1 (number function working on is decreased)
Algorithm Has9(n): Input: Integer n Output: whether 9 appears in decimal expansion of n if (n mod 10)=9 then return true else if (n<10) then return false else return Has9(n/10)
ADS2 lecture 6
has9
36
Does Has9 satisfy rules 1 and 2? Yes!
Rule 1 (number function working on is decreased)
Rule 2 ( stopping case)
Algorithm Has9(n): Input: Integer n Output: whether 9 appears in decimal expansion of n if (n mod 10)=9 then return true else if (n<10) then return false else return Has9(n/10)
ADS2 lecture 6
has9
37
Does Has9 satisfy rules 1 and 2? Yes!
Rule 1 (number function working on is decreased)
Rule 2 ( stopping case)
Algorithm Has9(n): Input: Integer n Output: whether 9 appears in decimal expansion of n if (n mod 10)=9 then return true else if (n<10) then return false else return Has9(n/10)
ADS2 lecture 6
has9
list
We have been defining lists in terms of nodes, where a node has
- a head (we call it “element” where we store data) - a tail (we call it “next” and it points to the next node or null)
This IS inherently recursive
Tail recursion
• Recursion is useful tool for designing algorithms with short, elegant definitions
• But comes at a cost – need to use memory to keep track of the state of each recursive call
• When memory is of primary concern, useful to be able to derive non-recursive algorithms from recursive ones.
• Can use a stack data structure to do this (see ADT chapter), but some cases we can do it more easily and efficiently
i.e. when algorithms use tail recursion• An algorithm uses tail recursion when recursion is linear
and recursive call is its very last operation
71ADS2 lecture 6