1 Chapter 3. Recursion Lecture 6
In functions and data structures
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) =
The factorial function in Java fact(4) = 4 * fact(3)
The factorial function in Java fact(4) = 4 * fact(3) = 4 * 3 * fact(2)
The factorial function in Java fact(4) = 4 * fact(3) = 4 * 3 * fact(2) = 4 * 3 * 2 * fact(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)
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 example Example 2: summing the elements of an array - Algorithm LinearSum(A,n): Input: An integer array A and integer n 1, 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) return1 call return1*1=1 2*1=2 3*2=6 4*6=24 final answer call ADS2 lecture 6 Actually we will remove the blue arrows on the right, to make it simpler
More examples
Raise m to the power n
We now have a recursive definition
Example 3: RaisePower Algorithm RaisePower(m,n): Input: Integers m,n Output: value of m n if n=0 then return 1 else return (m*RaisePower(m,n-1))
Example 3: RaisePower Algorithm RaisePower(m,n): Input: Integers m,n Output: value of m n if n=0 then return 1 else return (m*RaisePower(m,n-1)) Does RaisePower satisfy rules 1 and 2? Yes!
Example 3: RaisePower Algorithm RaisePower(m,n): Input: Integers m,n Output: value of m n if n=0 then return 1 else return (m*RaisePower(m,n-1)) 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 m n if n=0 then return 1 else return (m*RaisePower(m,n-1)) Does RaisePower satisfy rules 1 and 2? Yes! Rule 1 (number function working on is decreased) Rule 2 ( stopping case)
ADS2 lecture 629 Recursion trace, m=2, n=4 RaisePower(2,4) return 1 return 2*1=2 return 2*8=16final answer 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
Another example … has9
has9 Given an integer (base 10) does it contain the digit 9?
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
ADS2 lecture 638
ADS2 lecture 639 McCreesh & Prosser arXiv : v1
ADS2 lecture 640
ADS2 lecture 641 Matula & Beck JACM 30(3) 1983
ADS2 lecture 642 Ostergard DAM 120 (2002)
ADS2 lecture 643 San Segundo C&OR 38 (2011)
ADS2 lecture 644 Fleiner, Irving & Manlove TCS 412 (2011)
ADS2 lecture 645
example reverse
Reverse an array
Example … for you palindrome
example Binary search
Note overloading
example All permutations of a string
perm
Ouch!
Arithmetic! (on natural numbers) example Similar to … Church Numerals
Recursive Arithmetic
example 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
list
NOTE: this is NOT destructive! It produces a new list!
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