0% found this document useful (0 votes)
15 views

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)
15 views

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
You are on page 1/ 18

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