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

n7 Recursion New

Uploaded by

naeemtahmoor
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views

n7 Recursion New

Uploaded by

naeemtahmoor
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 37

Presentation for use with the textbook Data Structures and

Algorithms in Java, 6th edition, by M. T. Goodrich, R. Tamassia,


and M. H. Goldwasser, Wiley, 2014

Recursion

© 2014 Goodrich, Tamassia, Goldwasser Recursion 1


The Recursion Pattern
 Recursion: when a method calls itself
 Classic example – the factorial function:
n! = 1· 2· 3· ··· · (n-1)· n
 Recursive definition:  1 if n  0
f ( n)  
 As a Java method: n  f (n  1) else

© 2014 Goodrich, Tamassia, Goldwasser Recursion 2


Content of a Recursive Method
 Base case(s)
 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.

© 2014 Goodrich, Tamassia,


Recursion Goldwasser 3
Visualizing Recursion
 Recursion trace  Example
 A box for each call
return 4*6 = 24 final answer
recursive call
recursiveFactorial (4)
 An arrow from each call return 3*2 = 6
caller to callee recursiveFactorial (3)
 An arrow from each call return 2*1 = 2

callee to caller recursiveFactorial (2)

showing return value call return 1*1 = 1

recursiveFactorial (1)

call return 1

recursiveFactorial (0)

© 2014 Goodrich, Tamassia,


Recursion Goldwasser 4
Binary Search
Search for an integer in an ordered list

© 2014 Goodrich, Tamassia, Goldwasser Recursion 5


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.

© 2014 Goodrich, Tamassia, Goldwasser Recursion 6


Analyzing Binary Search
 Runs in O(log n) time.
 The remaining portion of the list is of size
high – low + 1
 After one comparison, this becomes one of
the following:

 Thus, each recursive call divides the search


region in half; hence, there can be at most
log n levels
© 2014 Goodrich, Tamassia, Goldwasser Recursion 7
Linear Recursion
 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 once
 Perform a single recursive call
 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.
© 2014 Goodrich, Tamassia, Goldwasser Recursion 8
Example of Linear Recursion
Recursion trace of linearSum(data, 5)
Algorithm linearSum(A, n): called on array data = [4, 3, 6, 2, 8]
Input:
Array, A, of integers
Integer n such that
0 ≤ n ≤ |A|
Output:
Sum of the first n
integers in A

if n = 0 then
return 0
else
return
linearSum(A, n - 1) + A[n - 1]

© 2014 Goodrich, Tamassia, Goldwasser Recursion 9


Reversing an Array
Algorithm reverseArray(A, i, j):
Input: An array A and nonnegative integer
indices i and j
Output: The reversal of the elements in A
starting at index i and ending at

if i < j then
Swap A[i] and A[ j]
reverseArray(A, i + 1, j - 1)
return

© 2014 Goodrich, Tamassia, Goldwasser Recursion 10


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 array reversal method as
reverseArray(A, i, j), not reverseArray(A)

© 2014 Goodrich, Tamassia, Goldwasser Recursion 11


Computing Powers
 The power function, p(x,n)=xn, can be
defined recursively:

 This leads to a power function that runs in


O(n) time (for we make n recursive calls)
 We can do better than this, however

© 2014 Goodrich, Tamassia, Goldwasser Recursion 12


Recursive Squaring
 We can derive a more efficient linearly recursive
algorithm by using repeated squaring:
 1 if x  0

p ( x, n)   x  p ( x, (n  1) / 2) 2 if x  0 is odd
 p ( x , n / 2) 2
if x  0 is even

 For example,
24 = 2(4/2)2 = (24/2)2 = (22)2 = 42 = 16
25 = 21+(4/2)2 = 2(24/2)2 = 2(22)2 = 2(42) = 32
26 = 2(6/ 2)2 = (26/2)2 = (23)2 = 82 = 64
27 = 21+(6/2)2 = 2(26/2)2 = 2(23)2 = 2(82) = 128

© 2014 Goodrich, Tamassia, Goldwasser Recursion 13


Recursive Squaring Method
Algorithm Power(x, n):
Input: A number x and integer n = 0
Output: The value xn
if n = 0 then
return 1
if n is odd then
y = Power(x, (n - 1)/ 2)
return x · y · y
else
y = Power(x, n/ 2)
return y · y
© 2014 Goodrich, Tamassia, Goldwasser Recursion 14
Analysis
Algorithm Power(x, n):
Input: A number x and
integer n = 0 Each time we make a
Output: The value xn recursive call we halve
if n = 0 then the value of n; hence,
we make log n recursive
return 1 calls. That is, this
if n is odd then method runs in O(log n)
y = Power(x, (n - 1)/ time.
2)
return x · y · y It is important that we
else use a variable twice
y = Power(x, n/ 2) here rather than calling
return y · y the method twice.
© 2014 Goodrich, Tamassia, Goldwasser Recursion 15
Tail Recursion
 Tail recursion occurs when a linearly recursive
method makes its recursive call as its last step.
 The array reversal method is an example.
 Such methods can be easily converted to non-
recursive methods (which saves on some resources).
 Example: algorithm reverseArray( )
Algorithm IterativeReverseArray(A, i, j ):
Input: An array A and nonnegative integer indices i and j
Output: The reversal of the elements in A starting at
index i and ending at j
while i < j do
Swap A[i ] and A[ j ]
i =i+1
j =j-1
return

© 2014 Goodrich, Tamassia, Goldwasser Recursion 16


Binary Recursion
 Binary recursion occurs whenever there are
two recursive calls for each non-base case.
 Example: Fibonacci sequence

f(1) = f(2) = 1
f(n) = f(n-1) + f(n-2) if n > 2

© 2014 Goodrich, Tamassia, Goldwasser Recursion 17


Computing Fibonacci Numbers
 Fibonacci numbers are defined recursively:
F0 = 0
F1 = 1
Fi = Fi-1 + Fi-2 for i > 1.
 Recursive algorithm (first attempt):
Algorithm BinaryFib(k):
Input: Nonnegative integer k
Output: The kth Fibonacci number Fk
if k = 1 then
return k
else
return BinaryFib(k - 1) + BinaryFib(k -
© 2014 Goodrich, Tamassia, 2)
Goldwasser Recursion 18
Binary Recursive Example
 Problem: add all the numbers in an integer array A:
Algorithm BinarySum(A, i, n):
Input: An array A and integers i and n
Output: The sum of the n integers in A starting at index i
if n = 1 then
return A[i]
return BinarySum(A, i, n/ 2) + BinarySum(A, i + n/ 2, n/ 2)

 Example trace:

0, 8

0, 4 4, 4
0, 2 2, 2 4, 2 6, 2

0, 1 1, 1 2, 1 3, 1 4, 1 5, 1 6, 1 7, 1

© 2014 Goodrich, Tamassia, Goldwasser Recursion 19


Recursion: Checklist
 Do I have a base case (base cases)?
 could be implicit (e.g., simply exit the function)

 Do I have a recursive call (recursive calls)?


 Do I “adjust” the argument(s) of the recursive call(s)
correctly?
 Can the recursive call(s) eventually reach the base
case(s)?
 Do I write the first call (e.g., in main()) correctly?

20
Running Time of Recursive
Algorithms
 Could be just a hidden “for" or “while” loop.
 See “Tail Recursion” slide.

 “Unravel” the hidden loop to count the number of

iterations.
 Example: sum of an array, reversing an array

 Logarithmic (next)
 Examples: binary search, exponentiation, GCD

 Solving a recurrence
 Example: merge sort, quick sort (later)

21
How to get better at writing recursive
algorithms?

 Close the textbook and lecture notes.

 Recall the algorithms in the lecture notes and


implement them in Java.

 Implement homework problems in Java.


 pay attention to the caller (main() method)

22
Multiple Recursion
 Multiple recursion:
 makes potentially many recursive calls
 not just one or two
 not covered in this course

© 2014 Goodrich, Tamassia, Goldwasser Recursion 23


Appendix: Saving Register Values
during Function Calls

24
25

LOGARITHMS
EECS 2011
26

Logarithmic Running Time


• An algorithm is O(logN) if it takes constant (O(1))
time to cut the problem size by a fraction (e.g., by
½).

• An algorithm is O(N) if constant time is required


to merely reduce the problem by a constant
amount (e.g., by 1).
27

Example: Binary Search


• Search for an element in a sorted array
• Sequential search
• Binary search

• Binary search
• Compare the search element with the middle element of
the array.
• If not equal, then apply binary search to half of the array
(if not empty) where the search element would be.
28

Binary Search
int binarySearch (int[] a, int x)
{
/*1*/ int low = 0, high = a.size() - 1;
/*2*/ while (low <= high)
{
/*3*/ int mid = (low + high) / 2;
/*4*/ if (a[mid] < x)
/*5*/ low = mid + 1;
/*6*/ else if (x < a[mid])
/*7*/ high = mid - 1;
else
/*8*/ return mid; // found
}
/*9*/ return NOT_FOUND;
}
29

Binary Search with Recursion


// Searches an ordered array of integers using recursion
int bsearchr(const int data[], // input: array
int low, // input: lower bound
int high, // input: upper bound
int value // input: value to find
) // return index if found, otherwise return –1

{ int middle = (low + high) / 2;


if (data[middle] == value)
return middle;
else if (low >= high)
return -1;
else if (value < data[middle])
return bsearchr(data, low, middle-1, value);
else
return bsearchr(data, middle+1, high, value);
}
30

Exponentiation xn
long exp(long x, int n)
/* A different version of function Power(x, n) */
{
/*1*/ if (n == 0)
/*2*/ return 1;
/*3*/ if (n == 1)
/*4*/ return x;
/*5*/ if (isEven(n))
/*6*/ return exp(x*x, n/2);
else
/*7*/ return exp(x*x, n/2)*x;
}
31

Euclid’s Algorithm
• Homework: trace the following algorithm. What is its running
time? (Hint: see next slide)
• Computing the greatest common divisor (GCD) of two integers

long gcd (long m, long n) // assuming m>=n


{
/*1*/ while (n!=0)
{
/*2*/ long rem = m%n;
/*3*/ m = n;
/*4*/ n = rem;
}
/*5*/ return m;
}
Euclid’s Algorithm (2)
• Theorem:
• If M > N, then M mod N < M/2.
• Max number of iterations:
• 2logN = O(logN)
• Average number of iterations:
• (12 ln 2 ln N)/2 + 1.47
Next Lecture
 Trees (section 8.1)
 Binary Trees (section 8.2)

 The next few slides show how to compute Fibonacci


numbers efficiently.
 for self-study, not on tests/exam

© 2014 Goodrich, Tamassia, Goldwasser Recursion 33


Appendix: Computing Fibonacci
Numbers
 Fibonacci numbers are defined recursively:
F0 = 0
F1 = 1
Fi = Fi-1 + Fi-2 for i > 1.
 Recursive algorithm (first attempt):
Algorithm BinaryFib(k):
Input: Nonnegative integer k
Output: The kth Fibonacci number Fk
if k = 1 then
return k
else
return BinaryFib(k - 1) + BinaryFib(k -
© 2014 Goodrich, Tamassia, 2)
Goldwasser Recursion 34
Analysis
 Let nk be the number of recursive calls by BinaryFib(k)
 n0 = 1
 n1 = 1
 n2 = n1 + n0 + 1 = 1 + 1 + 1 = 3
 n3 = n2 + n1 + 1 = 3 + 1 + 1 = 5
 n4 = n3 + n2 + 1 = 5 + 3 + 1 = 9
 n5 = n4 + n3 + 1 = 9 + 5 + 1 = 15
 n6 = n5 + n4 + 1 = 15 + 9 + 1 = 25
 n7 = n6 + n5 + 1 = 25 + 15 + 1 = 41
 n8 = n7 + n6 + 1 = 41 + 25 + 1 = 67.
 Note that nk at least doubles every other time
 That is, n > 2 . It is Recursion
k exponential!
k/2
© 2014 Goodrich, Tamassia, Goldwasser 35
A Better Fibonacci Algorithm
 Use linear recursion instead
Algorithm LinearFibonacci(k):
Input: A nonnegative integer k
Output: Pair of Fibonacci numbers (Fk , Fk-1)
if k = 1 then
return (k, 0)
else
(i, j) = LinearFibonacci(k - 1)
return (i +j, i)

 LinearFibonacci makes k-1 recursive calls

© 2014 Goodrich, Tamassia, Goldwasser Recursion 36


37

You might also like