0% found this document useful (0 votes)
8 views39 pages

2 Recursion

This document covers the concept of recursion in data structures and algorithms, including its definition, applications, and methods for implementing recursive solutions. It highlights the advantages and disadvantages of recursion, such as simplicity in code versus increased memory usage. Additionally, it explains tracing recursive methods, tail recursion, and provides examples of recursive algorithms like factorial and Fibonacci.
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)
8 views39 pages

2 Recursion

This document covers the concept of recursion in data structures and algorithms, including its definition, applications, and methods for implementing recursive solutions. It highlights the advantages and disadvantages of recursion, such as simplicity in code versus increased memory usage. Additionally, it explains tracing recursive methods, tail recursion, and provides examples of recursive algorithms like factorial and Fibonacci.
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/ 39

STIAK1124

Data Structures &


Algorithms Analysis

TOPIC 2 : RECURSION
2

Learning Objectives
At the end of this lesson, the student should be able to:
• Identify program with recursive method
• Trace recursive method
• Determine the efficiency of recursive method
• Identify tail recursion and replace it with iteration
• Write recursive method
3

What Is Recursion?

• A problem-solving process that can be used to


generate simple solutions (design of algorithm).
• Technique related to repetition. It is an
alternative way of solving repetition problem.
• Breaking a problem into identical but smaller
problems. The smaller problems are identical or
“self similar process” except for their size.
• Using that solution to solve the previous
problems
• Eventually the original problem is solved
4

Applications of Recursive
Algorithms
• The fields of Artificial Intelligent – games, proving
mathematical theorem, recognizing pattern, etc.
• Mathematical operations – computing factorial, greatest
common divisors, exponential functions, printing
permutations, etc.
• Operations on data structures – String, array, list, tree,
graph, etc.
• To design very efficient searching techniques - linear and
binary search.
• Divide and conquer algorithms – sorting techniques, etc.
• Backtracking algorithms – puzzle, nonlinear data
structures traversal, etc.
5

Recursive Methods
A recursive method is a method that calls itself.
Each time it is called, the recursive method can
operate on different arguments.
Generally, a recursive solution is slightly less
efficient, in terms of computer time, than an iterative
one because of the overhead for the extra method
calls.
In many instances, however, recursion enables us to
specify a natural, simple solution to a problem that
otherwise would be difficult to solve.
6

Recursive Solution
• A procedure for a particular task in terms of
applying the same procedure to a similar but
smaller task.
• Recognize the base case (the task is so simple that no
recursion is needed) can be implicit.
• Recognize the recursive case (the repetition part) and a
strategy to split this part into smaller versions of itself.
• Each recursive case must make progress towards the
base case.
• Combine the solutions to the smaller problem in such a
way that each larger problem is solve correctly.
7

Recursive Solution
8

Recursion: How does it work


NON-RECURSIVE
void countDown (int n)
{
for (int i=n; i>=1; i--)
System.out.println(i);

// Task: Counts down from a given positive integer.


// from n to 1
public static void countDown(int n)
{ System.out.println(n); Why do
e
countDown(n - 1); this fun s
ction
} // end countDown not wor
k???
9

Recursion: How does it work


Example n=3
countDown(3) countDown(2) countDown(1) countDown(0) ...
cout<<3 cout<<2 cout<<1 cout<<0
countDown(2) countDown(1) countDown(0) countDown(-1)
We're stuck in an infinite loop again.

/** Task: Counts down from a given positive integer.


* @param integer an integer > 0 */
public static void countDown(int integer)
{ System.out.println(integer);
if (integer > 1) Stopping condition
countDown(integer - 1);
} // end countDown
10

Requirements Of Recursive
Method
• A method calls itself
• Must have one (or more) a non recursive solution
base case (stopping case) and recursive case
(repetition case).
• Method definition must provide a parameter(or
more)
• Leads to different cases
• Includes an if or a switch statement
11

Two forms for recursive


algorithms
if the stopping case is reached
Solve it.
else
Split the problem into simpler cases using recursion.

if the stopping case is not reached


Split the problem into simpler cases using recursion.
12

Tracing a Recursive Method


• For each call to a method (be it recursive or not), java
records the state of the method, including the values of its
parameters and local variables.
• Each record, called an activation record, is analogous to a
piece of paper.
• The records are placed into an abstract data type (ADT)
called a stack.
13

Tracing a Recursive Method


public static void countDown(int integer)
{ System.out.println(integer);
if (integer > 1)
countDown(integer - 1);
} // end countDown

The effect of method call countDown(3)


14

Tracing a Recursive Method

Tracing the recursive call


countDown(3)
15

Tracing a Recursive Method

Note:
Note:thethe
recursive
recursive
method
methodwill will
use
usemore
more
memory
memory
than
thananan
iterative
iterative
method
methoddue due
to
tothe thestack
stack
ofofactivation
activation
records
records

The stack of activation records during the execution of a


call to countDown(3)
16

Tracing a Recursive Method


\\ calculate 12 + 22 + 32 + 42 + …
17

Tracing a Recursive Method


18

Recursive Methods That Return


a Value
• Task: Compute the sum
1 + 2 + 3 + … + n for an integer n > 0

public static int sumOf(int n)


{
if (n = = 1)
return 1;
// base case
else
return n + sumOf(n - 1);// recursive
case

} // end sumOf
19

Recursive Methods That Return


a Value

The stack of activation records


during the execution of a call to sumOf(3)
20

Recursive Method: Factorial function


• The factorial N! is defined for integers N≥0 as
N! = N * (N-1) * (N-2) * (N-3) * ... * 3 * 2 *1
For example 4! = 4 * 3 * 2 * 1 = 24
For N=0, we define 0! = 1.
Note the factorial is perfect for recursion because
N! = N * (N-1)! = N * (N-1) * (N-2)!
= N * (N-1) * (N-2) * (N-3)! ...
= N * (N-1) * (N-2) *...* 0!

A function definition:

1 if n=1 or n=0
fac(n) = n * fac(n-1) if n>1
21

Recursive Method: Factorial


function
int factorial (int n) public static long fac(int n)
{ {
int total = 1; if (n <= 1)
return 1;
for (int i=1; i<=n; i++)
else
total *= i; return n * fac(n-1)
return total; }
}

fac(4) // 24
return 4* fac(3) // 4 * 6 = 24
return 3* fac(2) // 3 * 2 = 6
return 2 * fac(1) // 2 * 1= 2

return 1
22

Recursive Tree (Calling Tree)


• If n= 10
n if n<=1
f(n) = n + f(½n) if n is even number, and n>1
f(½ (n+1)) + f(½ (n-1)) if n is odd number, and n>1

F (10) 10+7=17

10 F (5) 4+3=7

F (2) 2+1=3
3+1=4 F (3)
F (1)
F (1)
2+1=3 F (2) 2
F (1) 1 1
2
1 1
1

1
23

Recursive Tree (Calling Tree)


• Given a function definition of f(n) :

n if n<=1
f(n) = n + f(½n) if n is even number, and n>1
f(½ (n+1)) + f(½ (n-1)) if n is odd number, and n>1

• If n=-5
F (-5)

-5
24

Recursively Processing an Array


• Some of the more powerful searching and sorting
algorithms often are stated recursively (usually is
implemented using an array)
• When processing array recursively, divide it into two pieces,
for example;
• Last element one piece, and the rest of the array could be the
other piece, or
• First element one piece, and the rest of the array could be the
other piece, or
• Divide the array into two halves
25

Recursively Processing an Array


public static void displayArray(int array[], int first, int
last)
{
System.out.print(array[first] + “ ”);//start from 1st element
if (first< last)
displayArray(array, first+1, last);
} // end display Array

public static void displayArray(int array[], int first, int


last)
{
if (first<= last)
{
displayArray(array, first, last-1);
System.out.print(array[last] + “ ”);//start from last
}
} // end display Array
26

Recursively Processing an Array

public static void displayArray(int array[], int first, int last)


{
if (first== last)
System.out.print(array[first] + " ");
else
{
int mid = (first + last)/2;
displayArray(array, first, mid);
displayArray(array, mid+1, last);
}
} // end display Array

Two arrays with middle elements within left halves


27

Recursively Processing a Chain of


Linked Nodes
• To write a method that processes a chain of
linked nodes recursively
• Use a reference to the chain's first node as the
method's parameter
• Then process public void display()
{ displayChain(head);
the first node System.out.println();
} // end display
• Followed by the
private void displayChain(Node current)
rest of the chain { if (current != null)
{ System.out.print(current.data
+ " ");
displayChain(current.next);
}
} // end displayChain
28

A Simple Solution to a Difficult


Problem

The initial configuration of the Towers of Hanoi


for three disks
29

A Simple Solution to a Difficult


Problem
Rules for the Towers of Hanoi game
1. Move one disk at a time. Each disk you move must be
a topmost disk.
2. No disk may rest on top of a disk smaller than itself.
3. You can store disks on the second pole temporarily, as
long as you observe the previous two rules.
30

A Simple Solution to a Difficult


Problem

The smaller problems in


a recursive solution for
four disks
31

A Simple Solution to a Difficult


Problem
• Algorithm for solution with 1 disk as the base case

Algorithm solveTowers(numberOfDisks, startPole, tempPole, endPole)


if (numberOfDisks == 1)
Move disk from startPole to endPole
else
{
solveTowers(numberOfDisks-1, startPole, endPole,
tempPole)
Move disk from startPole to endPole
solveTowers(numberOfDisks-1, tempPole, startPole,
endPole)
}
32

A Poor Solution to a Simple


Problem
• Fibonacci numbers
• First two numbers of sequence are 1 and 1
• Successive numbers are the sum of the previous two
• 1, 1, 2, 3, 5, 8, 13, …
• This has a natural looking recursive solution
• Turns out to be a poor (inefficient) solution
33

A Poor Solution to a Simple


Problem
• The recursive algorithm

Algorithm Fibonacci(n)
if (n <= 1)
return 1
else
return Fibonacci(n-1) + Fibonacci(n-
2)
34

A Poor Solution to a Simple


Problem Time efficiency grows
exponentially with n

int fib(int n){


int i, twoBack, oneBack, current;
if (n <= 1)
return 1;
else {
twoBack=0; oneBack=1;
for (i=2; i<=n;i++){
current=twoBack + oneBack;
twoBack=oneBack;
oneBack=current;
}
Iterative solution is O(n) return current;
}
}

The computation of the Fibonacci number F6


(a) recursively; (b) iteratively
35

Calling Trees
• Definition:
Fn = Fn-1 + Fn-2 , if n > 1
Fn = n, if n = 0 or 1
36

Indirect Recursion
Direct recursion is a
function calling itself.
When f() calls g() and
g() calls f(), we have
mutual recursion.
More generally, cycle
of function calls is
known as indirect
recursion.
37

Tail Recursion
• Occurs when the last action performed by a
recursive method is a recursive call
public static void countDown(int integer)
{ System.out.println(integer);
if (integer > 1)
countDown(integer - 1);
} // end countDown

• This performs a repetition that can be done more


efficiently with iteration
• Conversion to iterative method is usually
straightforward
38

Tail Recursion
 The significance of tail recursion is that when making a tail-
recursive call, the caller's return position need not be saved on the
call stack; when the recursive call returns, it will branch directly on
the previously saved return position. Therefore, on compilers which
support tail-recursion optimization, tail recursion saves both space
and time.
//INPUT: Integers x, y such that x >= y and y > 0
int gcd(int x, int y) {
if (y == 0)
return x;
else
return gcd(y, x % y);
}
39

Conclusion
• Advantage of implementing recursion:
• Code is more simpler : easy to understand and to write code.

• Disadvantage:
• Use more memory (activation records)

You might also like