0% found this document useful (0 votes)
7 views32 pages

Recusrsion Waris

The document provides an overview of recursion in programming, explaining its definition, structure, and examples, particularly focusing on recursive functions and their implementation. It discusses concepts such as base cases, recursive calls, linear recursion, and tail recursion, as well as practical examples like calculating factorials and reversing arrays. Additionally, it touches on pitfalls of recursion and introduces binary search as a non-linear recursive method.

Uploaded by

ziaa0880
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)
7 views32 pages

Recusrsion Waris

The document provides an overview of recursion in programming, explaining its definition, structure, and examples, particularly focusing on recursive functions and their implementation. It discusses concepts such as base cases, recursive calls, linear recursion, and tail recursion, as well as practical examples like calculating factorials and reversing arrays. Additionally, it touches on pitfalls of recursion and introduces binary search as a non-linear recursive method.

Uploaded by

ziaa0880
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/ 32

DATA STRUCTURE & ALGORITHMS

RECURSION (part 1)

Waris Ali
NUML, Islamabad
What is Recursion?
• Recursion: comes from re occurance

• In Mathematics: repetition of steps to give


result

• In Programming: Recursion occurs when a


method calls itself to solve a simpler version of
the problem. With each recursive call, the
problem is different from, and simpler than, the
original problem.

3/1/2024 2
What is Recursion?
• Recursion involves the internal use of a stack.

• A stack is a data abstraction that works like


this: New data is "pushed," or added to the
top of the stack. When information is removed
from the stack it is "popped," or removed from
the top of the stack.

• The recursive calls of a method will be stored


on a stack, and manipulated in a similar
manner.

3/1/2024 3
Recursively Defined Sequences
• Often it is difficult to express the members of an
object or numerical sequence explicitly.
• EG: The Fibonacci sequence:
• {fn } = 0,1,1,2,3,5,8,13,21,34,55,…
• There may, however, be some “local” connections
that can give rise to a recursive definition –a
formula that expresses higher terms in the
sequence, in terms of lower terms.
• EG: Recursive definition for {fn }:
INITIALIZATION: f0 = 0, f1 = 1
RECURSION: fn = fn-1+fn-2 for n > 1.
L16 4
3/1/2024 4
Recursive Functions

It is possible to think of any function with domain


N as a sequence of numbers, and vice-versa.
Simply set: fn =f (n)
For example, our Fibonacci sequence becomes
the Fibonacci function as follows:
f (0) = 0, f (1) = 1, f (2) = 1, f (3) = 2,…
Such functions can then be defined recursively by
using recursive sequence definition. EG:
INITIALIZATION: f (0) = 0, f (1) = 1
RECURSION: f (n)=f (n -1)+f (n -2), for n > 1.
L16 5
3/1/2024 5
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.
• The base case is a fundamental situation where no further
problem solving is necessary.
• In the case of finding factorials, the answer of 0! is by definition
== 1. No further work is needed.

• Recursive calls.
• Calls to the current method.
• Each recursive call should be defined so that it makes progress
towards a base case.
3/1/2024 Department of IT, NUML Islamabad, Autumn 2011 6
Recursion Example – Solving Factorials

• The factorial operation in mathematics is illustrated below.

0! = 1
1! = 1 * 1 or 1 * 0!
2! = 2 * 1 or 2 * 1!
3! = 3 * 2 * 1 or 3 * 2!
4! = 4 * 3 * 2 *1 or 4 * 3!

Notice that each successive line can be solved in terms of


the previous line. For example, 4! is equivalent to the
problem

4 * 3!

3/1/2024 7
Recursion Example – Solving Factorials

• Classic example: Here is the non-recursive definition of the factorial


function:
• n! = 1· 2· 3· ··· · (n-1)· n

• Here is the recursive definition of a factorial:


(here f(n) = n!)

 1 if n  0
f ( n)  
n  f (n  1) else

• Code of recursive procedures, in functional programming languages


like Java, is almost identical to a recursive definition!

3/1/2024 8
Using A Recursive Method
• A recursive method to solve the factorial problem is given below.
Notice in the last line of the method the recursive call.
• The method calls another implementation of itself to solve a smaller
version of the problem.

int fact(int n)
// returns the value of n!
// precondition: n >= 0
{
if (n == 1 || n == 0)
return 1;
else
return n * fact(n - 1);
}
 The base case is a fundamental situation where no further problem
solving is necessary.
 In the case of finding factorials, the answer of 0! & 1! is by definition
== 1. No further work is needed.
Recursion – Step By Step
• Suppose we call the method to solve fact(4).
• This will result in four calls of method fact.

fact(4): This is not the base case (n==1) so we return the result of 4 *
fact(3). This multiplication will not be carried out until an answer is
found for fact(3). This leads to the second call of fact to solve
fact(3).

fact(3): Again, this is not the base case and we return


3 * fact (2). This leads to another recursive call to solve fact(2).

fact(2): Still, this is not the base case, we solve 2 * fact(1).

fact(1): Finally we reach the base case, which returns the value 1.
Recursion – Step By Step
• When a recursive call is made, the current computation is
temporarily suspended and placed on the stack with all its
current information available for later use.

• A completely new copy of the method is used to evaluate


the recursive call.

• When that is completed, the value returned by the


recursive call is used to complete the suspended
computation.

• The suspended computation is removed from the stack


and its work now proceeds.
Recursion – Step By Step

• When the base case is encountered the recursion will now


unwind and result in a final answer.

• The expressions below should be read from right to left.

fact(4) = 4 * fact(3) = 3 * fact(2) = 2 * fact(1) = 1


24  4 * 6  3 * 2  2 * 1
Recursion – The Picture
• Here is a picture. Look at what happens:

fact (4) 24
•Each box represents a call of
method fact. To solve fact(4)
requires four calls of method
fact (4)
fact.
4 * fact (3) 6
•Notice that when the
fact (3)
recursive calls were made
inside the else statement, the
3 * fact (2) 2 value fed to the recursive call
was (n-1). This is where the
problem is getting smaller and
fact (2)
simpler with the eventual goal
2 * fact (1) 1 of solving 1!.

fact (1)
Pitfalls Of Recursion
• If the recursion never reaches the base case, the recursive
calls will continue until the computer runs out of memory
and the program crashes.
• The message “stack overflow error” or “heap storage
exhaustion” indicates a possible runaway recursion.
• When programming recursively, you need to make sure
that the algorithm is moving toward the base case.
• Each successive call of the algorithm must be solving a
simpler version of the problem.
• Any recursive algorithm can be implemented iteratively,
but sometimes only with great difficulty.
• However, a recursive solution will always run more slowly
than an iterative one because of the overhead of opening
and closing the recursive calls.
Recursion Examples

• On the next few slides, you will see some


examples of how recursion is used in
programming.
• You should take out a sheet of paper and
a pencil and try to work each of them out
by hand.
Recursion – Example #2

int result = identity(10); returned


identity(num)
System.out.println("The final answer is " + value
result); identity (0) 10

public int identity(int num) identity (2) 12

{ identity (4) 16

if (num < 1) identity (6) 22

return 10; identity (8) 30

else identity (10) 40

return num + identity(num


- 2);
}

The final answer is 40.


Recursion - Example #3
returned
int result2 = negative(-3); negative(num) value
System.out.println("The final negative(21) -5
answer is " + result2); negative(17) 29
public int negative(int num) negative(13) 55
negative(9) 73
{
negative(5) 83
if (num >= 20)
negative(1) 85
return -5; negative(-3) 79
else
return negative(num +
4) + 2 * num;
}
The final answer is 79.
Recursion – Example #4

product(num) returned value


int result3 = product(1);
product(64) -1
System.out.println("The final answer32is " +
product(-32)
result3); product(16) 512
public int product(int num) product(-8) -4096
{ product(4) -16384

if (num > 20) product(-2) 32768


product(1) 32768
return -1;
else
return num * product(-2 * num);
}

The final answer is 32768.


DATA STRUCTURE & ALGORITHMS

RECURSION (part 2)

Waris Ali
NUML, Islamabad
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 at each step . (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.

3/1/2024 20
A Simple Example of Linear Recursion
Algorithm LinearSum(A, n):
Input:
An integer array A and an Example recursion trace:
integer n = 1, such that A has at
least n elements
call return 15 + A [4] = 15 + 5 = 20
Output:
LinearSum (A ,5)
The sum of the first n integers in
call return 13 + A[3] = 13 + 2 = 15
A
LinearSum (A ,4)
if n = 1 then
call return 7 + A [2] = 7 + 6 = 13
return A[0]
LinearSum (A ,3)
else
call return 4 + A [1] = 4 + 3 = 7
return LinearSum(A, n - 1) + A[n LinearSum (A,2)
- 1]
call return A[0] = 4

LinearSum (A,1)

3/1/2024 21
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 then
Swap A[i] and A[ j]
ReverseArray(A, i + 1, j - 1)
return

3/1/2024 22
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).

3/1/2024 23
Computing Powers

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

• This leads to an power function that runs in O(n) time (for we make n
recursive calls).

 1 if n  0
p ( x, n )  
 x  p( x, n  1) else

• We can do better than this, however.

3/1/2024 24
Tail Recursion
• Tail recursion occurs when a linearly recursive method
makes its last 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 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

3/1/2024 25
Tail Recursion Examples
• Every linear recursion can be converted to tail
recursion
• Example:
int f=1;
int fact(int n)
// returns the value of n!
// precondition: n >= 0
{
if (n == 1 || n == 0)
return f;
else
f=f*n;
fact(n - 1);

3/1/2024 26
Tail Recursion Examples

f =1
call

Factorial (4)

call f= 1*4 = 4

recursiveFactorial (3 )

call f= 4 *3 = 112

recursiveFactorial (2 )

call f= 12*2 = 24

recursiveFactorial (1 )

return 24 final answer

3/1/2024 27
BINARY-SEARCH
Alg.: BINARY-SEARCH (A, lo, hi, x)
if (lo > hi)
return FALSE
mid  (lo+hi)/2
if x = A[mid]
return TRUE
if ( x < A[mid] )
BINARY-SEARCH (A, lo, mid-1, x)
if ( x > A[mid] )
BINARY-SEARCH (A, mid+1, hi, x)

Consider the below given array & draw recursion trees for
searching 11 & 8 using binary search
1 2 3 4 5 7 9 11 28
Non 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 more than once.
• Perform more than one recursive call at each step
• Define each possible recursive call so that it makes
progress towards a base case.

3/1/2024 29
Fibonacci Series
Every element is the sum of its predecessors: 1, 1, 2, 3, 5, 8, 13, 21…

Recursive algorithm
fib(0) = 0
fib(1) = 1
fib(n) = fib(n-1) + fib(n-2) :n > 1

int fib(int n)
{
if (n == 1 || n == 0)
return n;
else
return fib(n-1)+fib(n-2);

30
31

Recursion Tree
Example 6

MergeSort(L)

1) if (length of L > 1) {
2) Split list into first half and second half
3) MergeSort(first half)
4) MergeSort(second half)
5) Merge first half and second half into sorted list
}

3/1/2024 32

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy