0% found this document useful (0 votes)
30 views18 pages

Recursion RT

Uploaded by

mthembua713
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
30 views18 pages

Recursion RT

Uploaded by

mthembua713
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Recursion

© 2013 Goodrich, Tamassia, Goldwasser Recursion 1


The Recursion Pattern
 One way to do repetition – loops
 Another way – recursion – very powerful tool
 Recursion: when a method calls itself 1/more times
 Classic example--the factorial function:
 n! = 1· 2· 3· ··· · (n-1)· n
 Recursive definition: n * f (n  1) if n  2
f ( n)  
 1 else
 As a Python method (runs at O(n)):
def fact(n):
Fact (4) = 4*3*2*1
Fact(4) = 4 * ( 3 * ( 2 * 1) if n>=2:
return n*fact(n-1)
else return 1

© 2013 Goodrich, Tamassia, Goldwasser Recursion 2


Properties of a Recursive
Method
Recursive solutions have 3 rules / properties:
 Base case(s) – the terminating case – when to stop
 Values of the input variables for which we perform no
recursive calls are called base cases (there should be at
least one base case).
 Every possible chain of recursive calls must eventually

reach a base case.


 Recursive calls
 Calls to the current method.

 Each recursive call should be defined so that it makes


progress towards a base case.
 Progress must be made towards the base
© 2013 Goodrich, Tamassia,
Recursion Goldwasser 3
Recursive Trace / Call Trees
 Used to develop / evaluate
a recursive function
 A box for each call
 Arrows show flow of
execution
 Dotted arrows show
returned values
 E.g. shows fact(5)
def fact(n):
if n>=2:
return n*fact(n-1)
else return 1

© 2013 Goodrich, Tamassia,


Recursion Goldwasser 4
Recursive Trace / Call Trees
Draw the call tree for:
def main():
y=foo(3)
bar(2)
def foo(x):
if x%2 != 0:
return 0
else return x + foo(x-1)
def bar(n):
if n>0:
print (n)
bar(n-1)
main()

© 2013 Goodrich, Tamassia,


Recursion Goldwasser 5
How does recursion work?
 When a function is called the flow of execution from where the call is made
is interrupted and execution jumps to the function.
 When the function ends, execution returns to where it was interrupted – in
the calling program
 How does the compiler know where to return?
 When a function is called, an activation record is created with function
info
 One piece of info is the return address – location of next instruction to be
executed when the function terminates
 A separate activation record is created for EACH function call – even to the
same function

© 2013 Goodrich, Tamassia,


Recursion Goldwasser 6
Recursive Binary Search
 Remember that when searching for an item
 we repeatedly compare to the middle item
 If its not found, we split the sequence in half – either top or bottom
half
 The same is repeated for this smaller sequence
 Reminder of our binary search – no recursion
def binary_search(A,val):
lower = 0 upper = len(A)-1
while lower <= upper:
mid = (lower+upper)//2
if val == A[mid]:
return True
elif val < A[mid]:
upper = mid-1
else:
lower = mid+1
return False
© 2013 Goodrich, Tamassia,
Recursion Goldwasser 7
Binary Search – a classic alg
 Search for an integer, target, in an ordered list, arr.
def binarySearch(arr, low, high, target):
# Check base case
if low<=high:
mid = (high + low) // 2
# If element is present at the middle itself
if arr[mid] == target:
return mid

# If element is smaller than mid, then it can only


# be present in left / lower subarray
elif arr[mid] > target:
return binarySearch(arr, low, mid - 1, target)

# Else the element can only be present in right subarray


else:
return binarySearch(arr, mid + 1, high, target)

else:
# Element is not present in the array
return -1

© 2013 Goodrich, Tamassia, Goldwasser Recursion 8


Visualizing Binary Search
 We consider three cases:
 If the target equals data[mid], then we have found the target.
 If target < data[mid], then we recur on the first half of the
sequence.
 If target > data[mid], then we recur on the second half of the
sequence.

© 2013 Goodrich, Tamassia, Goldwasser Recursion 9


Analyzing Binary Search
 Runs in O(log n) time.
 Because each recursive call divides the
search region in half; there can be at most
log n levels.

© 2013 Goodrich, Tamassia, Goldwasser Recursion 10


Types of Recursion
 Linear Recursion
 The body of the function makes at most ONE new call to the
recursive function (binary search & factorial)
 Binary search runs at O(logn) time constraint
 Other linear recursion runs at O(n) time – e.g. factorial
 Binary Recursion
 The body of the function makes TWO recursive calls to the
recursive function (Fibonacci)
 Often runs at O(n2)
 Multiple Recursion
 The body of the function makes more than TWO calls to the
recursive function
 Often runs at O(nk), where k is the number of recursive calls in
the function

© 2013 Goodrich, Tamassia, Goldwasser Recursion 11


Designing Recursion algorithms
 Test for base cases
 Begin by testing for a set of base cases (there should be
at least one).
 Every possible chain of recursive calls must eventually
reach a base case, and the handling of each base case
should not use recursion.
 Recur
 Perform 1/more recursive calls
 This step may have a test that decides which of several
possible recursive calls to make, but it should ultimately
make just one of these calls
 Define each possible recursive call so that it makes
progress towards a base case.
© 2013 Goodrich, Tamassia, Goldwasser Recursion 12
Defining Arguments for Recursion
 In creating recursive methods, it is important to define
the methods in ways that facilitate recursion.
 This sometimes requires we define additional
parameters that are passed to the method.
 For example, we defined the binary search method as
binary_search(Array, low, high, target), not
binary_search(Array, target)

© 2013 Goodrich, Tamassia, Goldwasser Recursion 13


Computing Powers
 The power function, p(x,n)=xn, can be
defined recursively:
ì 1 if n = 0
p ( x , n) = í
î x × p( x, n - 1) else
 This leads to an power function that runs in
O(n) time (for we make n recursive calls).
Power(2,5) =return 2* power(2,4)
def power(x,n): return 2* 2* power(2,3)
if n == 0: return 2*2*2*power(2,2)
return 1 return 2*2*2*2*power(2,1)
else: return 2*2*2*2*2*power(2,0
return x* power(x, n-1) return 2*2*2*2*2*1
32

© 2013 Goodrich, Tamassia, Goldwasser Recursion 14


Tail Recursion
 Tail recursion occurs when a linearly recursive
method makes its recursive call as its last step.
 The binary_search method is an example.
 Such methods can easily be converted to non-
recursive methods (which saves on some resources).
def binarySearch(arr, low, high, target):
if low<=high:
mid = (high + low) // 2
if arr[mid] == target:
return mid
elif arr[mid] > target:
return binarySearch(arr, low, mid - 1, target)
else:
return binarySearch(arr, mid + 1, high, target)
else:
return -1

© 2013 Goodrich, Tamassia, Goldwasser Recursion 15


Tail Recursion
def binary_search(A,target):
lower =
upper = len(A)-1
while lower <= upper:
mid = (lower+upper)//2
if target == A[mid]:
return True
elif target < A[mid]:
upper = mid-1
else:
lower = mid+1
return False

© 2013 Goodrich, Tamassia, Goldwasser Recursion 16


Binary Recursion- Fibonacci Numbers
 Fibonacci numbers are defined recursively:
F0 = 0
F1 = 1
Fi = Fi-1 + Fi-2 for i > 1.
 Recursive algorithm (first attempt):
 A call to the function fib(n) – has the
recursive call return fib(n-1) + fib(n-2)
 So for each n, fib is called twice
 Therefore the time complexity is O(n2)

© 2013 Goodrich, Tamassia, Goldwasser Recursion 17


Binary Recursion- Fibonacci Numbers
def fib(n): # find the nth fibonacci number
if n > 1:
return fib(n-1)+fib(n-2)
else:
return n

© 2013 Goodrich, Tamassia, Goldwasser Recursion 18

You might also like