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

Week 3-4 Recursion REVISED

Uploaded by

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

Week 3-4 Recursion REVISED

Uploaded by

lama alessa
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 37

PROGRAMMING WITH RECURSION

1
COPYRIGHT © 2005, MICHAEL T. GOODRICH AND ROBERTO TAMASSIA.
3.5 Recursion
2

 We have seen that repetition can be achieved by writing loops, such as


for loops and while loops. Another way to achieve repetition is
through recursion, which occurs when a function calls itself.
 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)  
n  f (n  1) else
 As a Java method:
Content of a Recursive Method
3

 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.
4
Visualizing Recursion

 Recursion trace Example recursion trace:


 A box for each recursive call return 4*6 = 24 final answer
call
recursiveFactorial(4)
 An arrow from each caller call return 3*2 = 6
to callee recursiveFactorial(3)
 An arrow from each call return 2*1 = 2

callee to caller showing recursiveFactorial(2)

return value call return 1*1 = 1


recursiveFactorial(1)
call return 1
recursiveFactorial(0)
Binary Search
5

 Binary search uses a recursive method to search an


array to find a specified value
 The array must be a sorted array:
a[0]≤a[1]≤a[2]≤. . . ≤ a[finalIndex]
 If the value is found, its index is returned
 If the value is not found, -1 is returned
 Note: Each execution of the recursive method
reduces the search space by about a half

© 2006 Pearson Addison-Wesley. All rights reserved


Binary Search
6

 An algorithm to solve this task looks at the middle of


the array or array segment first
 If the value looked for is smaller than the value in the
middle of the array
 Then the second half of the array or array segment can be
ignored
 This strategy is then applied to the first half of the array or
array segment

© 2006 Pearson Addison-Wesley. All rights reserved


Binary Search
7

 If the value looked for is larger than the value in the middle of
the array or array segment
 Then the first half of the array or array segment can be ignored
 This strategy is then applied to the second half of the array or array
segment
 If the value looked for is at the middle of the array or array
segment, then it has been found
 If the entire array (or array segment) has been searched in this
way without finding the value, then it is not in the array

© 2006 Pearson Addison-Wesley. All rights reserved


Pseudocode for Binary Search
8

© 2006 Pearson Addison-Wesley. All rights reserved


Recursive Method for Binary
9
Search

© 2006 Pearson Addison-Wesley. All rights reserved


Execution of the Method search
(Part 1 of 2)
10

© 2006 Pearson Addison-Wesley. All rights reserved


Execution of the Method search
(Part 1 of 2)
11

© 2006 Pearson Addison-Wesley. All rights reserved


3.5.1 Linear Recursion
12

 The simplest form of recursion is linear recursion, where a


method is defined so that it makes at most one recursive
call each time it is invoked. This

 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 recursive step may involve a
test that decides which of several possible recursive calls to make,
but it should ultimately choose to make just one of these calls each
time we perform this step.)
 Define each possible recursive call so that it makes progress towards
a base case.
Summing the Elements of an Array Recursively
13

 Suppose, for example, we are given an array, A, of


n integers that we wish to sum together. We can
solve this summation problem using linear
recursion by observing that the sum of all n
integers in A is equal to A[0], if n = 1, or the sum of
the first n − 1 integers in A plus the last element in
A.

2 Dec 2023 Computer Science Department


A Simple Example of Linear
14
Recursion

Example recursion trace:


Algorithm LinearSum(A, n)
{
call return 15 + A[4] = 15 + 5 = 20
Input :
LinearSum (A,5)
A integer array A and an integer
call return 13 + A[3] = 13 + 2 = 15
n such that A has at least n
LinearSum (A,4)
elements
call return 7 + A[2] = 7 + 6 = 13
Output :
LinearSum (A,3)
The sum of the first n integers in A call return 4 + A[1] = 4 + 3 = 7

LinearSum (A,2)
if ( n = 1) return A[0]; call return A[0] = 4
else LinearSum (A,1)
return LinearSum(A, n - 1) + A[n];
}
15

Output:

20

2 Dec 2023 Computer Science Department


16
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).
17
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 j
if (i < j )
{
swap A[i] and A[j];
ReverseArray(A, i + 1, j - 1);
}
}
18

Output:

54321
2 Dec 2023 Computer Science Department
Tail Recursion
19

Using recursion can often be a useful tool for designing


algorithms that have elegant, short definitions. But this
usefulness does come at a modest cost. When we use a
recursive algorithm to solve a problem, we have to use some of
the memory locations in our computer to keep track of the state
of each active recursive call. When computer memory is at a
premium, then, it is useful in some cases to be able to derive
non-recursive algorithms from recursive ones.

 Tail recursion occurs when a linearly recursive method


makes its recursive call as its last step.

2 Dec 2023 Computer Science Department


20
Tail Recursion
 The array reversal method is an example.
 Such methods can be easily converted to non-recursive
methods (which saves on some resources).
 Example:

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 )
{ swap A[i] and A[j];
i = i + 1;
j = j – 1;
}
}
Computing Powers
21

 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).
 We can do better than this, however.
22
Recursive Squaring

 We can derive a more efficient linearly recursive algorithm


by using repeated squaring:
 1 if n  0

p ( x, n)   x  p ( x, (n  1) / 2) 2 if n  0 is odd
 p ( x , n / 2 ) 2
if n  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.
23
A Recursive Squaring Method

Algorithm Power(x, n)
{
Input : A number x and integer n = 0
Output : The value xn
if (n = 0) return 1;
if (n is odd )
{ y = Power(x, (n - 1)/ 2);
return x*y*y; }
else
{ y = Power(x, n/ 2);
return y*y; }
}
Analyzing the Recursive Squaring Method
24

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 the
value of n; hence, we make
if (n = 0) return 1; log n recursive calls. That
if (n is odd ) is, this method runs in
{ y = Power(x, (n - 1)/ 2); O(log n) time.

return x*y*y; }
It is important that we
else used a variable twice here
{ y = Power(x, n/ 2); rather than calling the
method twice.
return y*y; }
}
25

Output:
power of 3^4 =81
power of 5^5 =3125
26
3.5.2 Binary Recursion

 Binary recursion occurs whenever there are two recursive


calls for each non-base case.
27
Binary Recursive Method

 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) 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
28

Output:

14
2 Dec 2023 Computer Science Department
29
Computing Fibanacci Numbers

 Fibonacci numbers are defined recursively:


F0 = 0
F1 = 1
Fi = Fi¡1 + Fi¡2 for i > 1.
 As a recursive algorithm (first attempt):

Algorithm BinaryFib(k)
{ Input : Nonnegative integer k
Output : The kth Fibonacci number Fk
if ( k = 1) return k;
else
return BinaryFib(k - 1) + BinaryFib(k - 2);
}
30

Output:
fibonacci of 7 =13
fibonacci of 2 =1
2 Dec 2023 Computer Science Department
Analyzing the Binary Recursion Fibonacci
Algorithm
31

 Let nk denote number of recursive calls made by


BinaryFib(k). Then
 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 the value at least doubles for every other value of
nk. That is, nk > 2k/2. It is exponential!
3.5.3 Multiple Recursion
32

 Generalizing from binary recursion, we use


multiple recursion when a method may make
multiple recursive calls, with that number
potentially being more than two.

2 Dec 2023 Computer Science Department


3.5.3 Multiple Recursion
33

 One of the most common applications of this type


of recursion is used when we wish to enumerate
various configurations in order to solve a
combinatorial puzzle.
 Solving a combinatorial puzzle by enumerating and
testing all possible configurations.
 One way to look at the is that it enumerates every
possible size-k ordered subset of U, and tests each
subset for being a possible solution to our puzzle.

2 Dec 2023 Computer Science Department


34
Algorithm for Multiple Recursion
Algorithm PuzzleSolve(k,S,U)
{
Input: An integer k, sequence S, and set U (the universe of elements to test)
Output: An enumeration of all k-length extensions to S using elements in U
without repetitions
for all e in U do
{
Remove e from U; // e is now being used
Add e to the end of S;
if (k = 1)
{
Test whether S is a configuration that solves the puzzle;
if ( S solves the puzzle ) return “Solution found: ” S;
else
PuzzleSolve(k - 1, S,U);
Add e back to U; // e is now unused
Remove e from the end of S;
}
35
Visualizing PuzzleSolve

Initial call

PuzzleSolve (3,(),{a,b,c})

PuzzleSolve (2,a,{b,c}) PuzzleSolve (2,b,{a,c}) PuzzleSolve (2,c,{a,b})

PuzzleSolve (1,ab ,{c}) PuzzleSolve (1,ba ,{c}) PuzzleSolve (1,ca,{b})


abc bac cab
PuzzleSolve (1,ac,{b}) PuzzleSolve (1,bc ,{a}) PuzzleSolve (1,cb ,{a})
acb bca cba
Exercises
36

 Describe a way to use recursion to add all the elements


in a n × n (two dimensional) array of integers.
 Describe a recursive algorithm for finding the
maximum element in an array A of n elements?
 Draw the recursion trace for the execution of method
PuzzleSolve(3,S, U) (Code Fragment 3.37), where S is
empty and U = {a,b,c,d}.
 Give a recursive algorithm to compute the product of
two positive integers, m and n, using only addition and
subtraction.
2 Dec 2023 Computer Science Department
37
References

Chapter 3.5, Data Structures and Algorithms by M.


Goodrich, R. Tamassia, M. Goldwasser .

You might also like