0% found this document useful (0 votes)
35 views46 pages

Recursion and Recursive Algorithms

This document provides an overview of recursion and recursive algorithms, detailing their definitions, types, and examples, such as calculating factorials and Fibonacci sequences. It outlines the advantages of recursion over iteration, including its applications in programming and data structures, while also discussing the complexities involved. Key concepts include base cases, the laws of recursion, and various recursion techniques like direct, indirect, and tree recursion.
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)
35 views46 pages

Recursion and Recursive Algorithms

This document provides an overview of recursion and recursive algorithms, detailing their definitions, types, and examples, such as calculating factorials and Fibonacci sequences. It outlines the advantages of recursion over iteration, including its applications in programming and data structures, while also discussing the complexities involved. Key concepts include base cases, the laws of recursion, and various recursion techniques like direct, indirect, and tree recursion.
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/ 46

RECURSION AND

RECURSIVE
ALGORITHMS
Dr. Paul Aazagreyir,( Ph.D., MSc, BSc)
LECTURE OBJECTIVES
By the end of this lecture, you will be able to

 Know the meaning of Recursion and a Recursive algorithm

 Understand the different types of recursive algorithms

 See some examples of recursive algorithms

 Understand how the recursive algorithm works

 Know the difference between recursion and iteration

 Know the reasons why recursion is preferred in programming

 Know the runtime and space complexity of different recursive algorithms


LECTURE OUTLINE
Recursion and Recursive Algorithms

Why use Recursion

Factorial Example

Purpose of Recursions

Conditionals to Start, Continue and Stop Recursion

The Three Laws of Recursion


LECTURE OUTLINE CONTINUOUS
 Types of Recursion

Direct Recursion

 Indirect Recursion

 Recursion versus Iteration

Some Recursive Algorithms (Examples)

Reversing an Array

 Fibonacci Sequence
Recursion and Recursive Algorithms
(Definitions)
Recursion is the process of defining something in terms of itself.

A physical world example would be to place two parallel mirrors facing


each other.

A recursive algorithm is an algorithm which calls itself with "smaller (or


simpler)" input values.

 And which obtains the result for the current input by applying simple operations
to the returned value for the smaller (or simpler) input.
MAIN INSTANCES OF RECURSION TECHNIQUES
Recursive technique (i.e. when recursion is used as a technique in which a
function makes one or more calls to itself).

Data structure technique(i.e. when a data structure uses smaller instances of the
exact same type of data structure when it represents itself).
USES OF RECURSION
Recursion provides an alternative for performing repetitions of the task in which
a loop is not ideal. Most modern programming languages support recursion.

 Recursion serves as a great tool for building out particular data structure. So
now let’s start with an example exercise of creating a factorial function.
FACTORIAL EXAMPLE
The factorial function is denoted with an exclamation point and is
defined as the product of the integers from 1 to n. Formally, we can state
this as:
n! = n ⋅ (n−1) ⋅ (n−2) … 3 ⋅ 2 ⋅ 1
Note, if n = 0, then n! = 1. This is important to take into account,
because it will serve as our base case.
Take this example:
4! = 4 ⋅ 3 ⋅ 2 ⋅ 1 = 24.
So how can we state this in a recursive manner? This is where the
concept of base case comes in.
FACTORIAL EXAMPLE CONTINUOUS
Base case is a key part of understanding recursion, especially when it
comes to having to solve interview problems dealing with recursion.
Let’s rewrite the above equation of 4! so it looks like this:
4! = 4 ⋅ (3 ⋅ 2 ⋅ 1) = 24
Notice that this is the same as:
4! = 4 ⋅ 3! = 24
Meaning we can rewrite the formal recursion definition in terms of
recursion like so:
n! = n ⋅ (n−1) !
Note, if n = 0, then n! = 1.
This means the base case occurs once n=0,
the recursive cases are defined in the equation above. Whenever you are
trying to develop a recursive solution it is very important to think about
the base case, as your solution will need to return the base case once all
the recursive cases have been worked through. Let’s look at how we can
create the factorial function in Python:
Python Code of a factorial
• def fact(n):
• '''
• Returns factorial of n (n!).
• Note use of recursion
• '''
• # BASE CASE!
• if n == 0:
• return 1
• # Recursion!
• else:
• return n * fact(n-1)
FACTORIAL EXAMPLE CONTINUOUS
Let’s see it in action! Fact (5) = 120
Note how we had an if statement to check if a base case occurred.
Without it this function would not have successfully completed running.
We can visualize the recursion with the following figure:
We can follow this flow chart from the top, reaching the base case, and
then working our way back up.
Recursion is a powerful tool, but it can be a tricky concept to implement.
FACTORIAL EXAMPLE CONTINUOUS
PURPOSE OF RECURSION

Recursive functions have many uses, but like any other kind of code, their
necessity should be considered.

 As discussed above, consider the differences between recursions and loops, and
use the one that best fits your needs.

 If you decide to go with recursions, decide what you want the function to do
before you start to compose the actual code.
Conditionals to Start, Continue, and Stop the Recursion
It’s important to look at any arguments or conditions that would start the
recursion in the first place.

 For example, the function could have an argument that might be a string or
array.

 The function itself may have to recognize the datatype versus it being recognized
before this point (such as by a parent function).

 In simpler scenarios, starting conditions may often be the exact same conditions
that force the recursion to continue.

More importantly, you want to establish a condition where the recursive action
Conditionals to Start, Continue, and Stop the
Recursion continuous
 These conditionals, known as base cases, produce an actual value rather than
another call to the function.

 However, in the case of tail-end recursion, the return value still calls a function
but gets the value of that function right away

The establishment of base cases is commonly achieved by having a conditional


observe some quality, such as the length of an array or the amount of a number,
just like loops.

However, there are multiple ways to go about it, so feel free to alter the
complexity as needed.
THE THREE LAWS OF RECURSION
All recursive algorithms must obey three important laws:
A recursive algorithm must have a base case, which denotes the point when it
should stop.

 A recursive algorithm must change its state and move toward the base case
which enables it to store and accumulate values that end up becoming the
answer.

A recursive algorithm must call itself, recursively with smaller and smaller values.
TYPES OF RECURSION
DIRECT RECURSION
 Tail Recursion:
If a recursive function calling itself and that recursive call is the last
statement in the function then it’s known as Tail Recursion. After that
call the recursive function performs nothing. The function has to
process or perform any operation at the time of calling and it does
nothing at returning time.
TYPES OF RECURSION CONTINUOUS
Example:
// Code Showing Tail Recursion
#include <iostream>
using namespace std;
// Recursion function
void fun(int n)
{
if (n > 0) {
cout << n << " ";
// Last statement in the function
fun(n - 1);
}
TYPES OF RECURSION CONTINUOUS
// Driver Code
int main()
{
int x = 3;
fun(x);
return 0;
}
TYPES OF RECURSION CONTINUOUS
Time Complexity For Tail Recursion : O(n)
Space Complexity For Tail Recursion : O(n)

Lets us convert Tail Recursion into Loop and compare each other in
terms of Time & Space Complexity and decide which is more efficient.
// Converting Tail Recursion into Loop
#include <iostream>
using namespace std;
void fun(int y)
{
while (y > 0) {
cout << y << " ";
TYPES OF RECURSION CONTINUOUS
// Driver code
int main()
{
int x = 3;
fun(x);
return 0;
}
Time Complexity: O(n)
Space Complexity: O(1)
So it was seen that in case of loop the Space Complexity is O(1) so it
was better to write code in loop instead of tail recursion in terms of
Space Complexity which is more efficient than tail recursion.
TYPES OF RECURSION CONTINUOUS(Head Recursion)
Head Recursion:
 If a recursive function calling itself and that recursive call is the first
statement in the function then it’s known as Head Recursion.
There’s no statement, no operation before the call. The function doesn’t have to
process or perform any operation at the time of calling and all
operations are done at returning time.
TYPES RECURSION CONTINUOUS(Head Recursion)
If a recursive function calling itself and that recursive call is the first
statement in the function then it’s known as Head Recursion.

 There’s no statement, no operation before the call. The function doesn’t have to
process or perform any operation at the time of calling and all
operations are done at returning time.
HEAD RECURSION CONTINUOUS
Example:
// C++ program showing Head Recursion
#include <bits/stdc++.h>
using namespace std;
// Recursive function
void fun(int n)
{
if (n > 0) {
// First statement in the function
fun(n - 1);
cout << " "<< n;
}
}
// Driver code
HEAD RECURSION CONTINUOUS
int main()
{
int x = 3;
fun(x);
return 0;
}
Time Complexity For Head Recursion: O(n)
Space Complexity For Head Recursion: O(n)
Let’s convert the above code into the loop.
// Converting Head Recursion into Loop
#include <iostream>
using namespace std;
HEAD RECURSION CONTINUOUS
// Recursive function
void fun(int n)
{
int i = 1;
while (i <= n) {
cout <<" "<< i;
i++;
}
}
// Driver code
int main()
{
int x = 3;
fun(x);
return 0;
TYPES OF RECURSION CONTINUOUS(Tree Recursion)
Tree Recursion:
To understand Tree Recursion let’s first understand Linear Recursion. If a recursive function
calling itself for one time then it’s known as Linear Recursion. Otherwise if a recursive function
calling itself for more than one time then it’s known as
Tree Recursion.
Example: Pseudo Code for linear recursion
fun(n)
{
// some code
if(n>0)
{
fun(n-1); // Calling itself only once
}
// some code
TYPES OF RECURSION CONTINUOUS(Tree Recursion)
Program for tree recursion
// C++ program to show Tree Recursion
#include <iostream>
using namespace std;
// Recursive function
void fun(int n)
{
if (n > 0)
{
cout << " " << n;
// Calling once
fun(n - 1);
// Calling twice
fun(n - 1);
}
TYPES OF RECURSION CONTINUOUS(Tree Recursion)
// Driver code
int main()
{
fun(3);
return 0;
}
Output:
3211211
Time Complexity For Tree Recursion: O(2n)
Space Complexity For Tree Recursion: O(n)s
DIRECT RECURSION CONTINUOUS
/ Driver code
int main()
{
int r;
r = fun(95);
cout << " " << r;
return 0;
}
TYPES OF RECURSION CONTINUOUS(Tree Recursion)
Nested Recursion:
In this recursion, a recursive function will pass the parameter as a
recursive call. That means “recursion inside recursion”. Let see the
example to understand this recursion.
Example:
// C++ program to show Nested Recursion
#include <iostream>
using namespace std;
int fun(int n)
{
if (n > 100)
return n - 10;
// A recursive function passing parameter
// as a recursive call or recursion inside
// the recursion
return fun(fun(n + 11));
INDIRECT RECURSION
• In this recursion, there may be more than one functions and they are calling one
another in a circular manner.
INDIRECT RECURSION CONTINUOUS
INDIRECT RECURSION CONTINUOUS
}
void funB(int n)
{
if (n > 1) {
cout <<" "<< n;
// Fun(B) is calling fun(A)
funA(n / 2);
}
}
// Driver code
int main()
{
funA(20);
return 0;
} Output:
RECURSION VERSUS ITERATION
The Recursion and Iteration both repeatedly execute the set of instructions.

 Recursion is when a statement in a function calls itself repeatedly.

The iteration is when a loop repeatedly executes until the controlling condition
becomes false.

 The primary difference between recursion and iteration is that recursion is a


process, always applied to a function and iteration is applied to the set of
instructions which we want to get repeatedly executed.
RECURSION VERSUS ITERATIONCONTINUOUS
RECURSION:
 Recursion uses selection structure.

 Infinite recursion occurs if the recursion step does not reduce the problem in a manner
that converges on some condition (base case) and Infinite recursion can crash the
system.

 Recursion terminates when a base case is recognized.

 Recursion is usually slower than iteration due to the overhead of maintaining the stack

Recursion uses more memory than iteration.


RECURSION VERSUS ITERATION CONTINUOUS
ITERATION:
 Iteration uses repetition structure.

 An infinite loop occurs with iteration if the loop condition test never becomes
false and Infinite looping uses CPU cycles repeatedly.

 An iteration terminates when the loop condition fails.

 An iteration does not use the stack so it's faster than recursion.

 Iteration consumes less memory.


Some Recursive Algorithms (Examples)
 Reversing an Array

Let us consider the problem of reversing the n elements of an array, A,


so that the first element becomes the last, the second element becomes
the second to the last, and so on. We can solve this problem using the
linear recursion, by observing that the reversal of an array can be
achieved by swapping the first and last elements and then recursively
reversing the remaining elements in the array.
SOME RECURSIVE ALGORITHMS (EXAMPLES) CONTINUOUS
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
SOME RECURSIVE ALGORITHMS (EXAMPLES) CONTINUOUS
Fibonacci Sequence
Fibonacci sequence is the sequence of numbers 1, 1, 2, 3, 5, 8, 13, 21,
34, 55, .... The first two numbers of the sequence are both 1, while each
succeeding number is the sum of the two numbers before it. We can
define a function F(n) that calculates the nth Fibonacci number.
First, the base cases are: F(0) = 1 and F(1) = 1.
Now, the recursive case: F(n) = F(n-1) + F(n-2).
Write the recursive function and the call tree for F(5).
Algorithm Fib(n) {
if (n < 2) return 1
Else return Fib(n-1) + Fib(n-2)
}
SOME RECURSIVE ALGORITHMS (EXAMPLES) CONTINUOUS
 The above recursion is called binary recursion since it makes two
recursive calls instead of one. How many number of calls are needed to
compute the kth Fibonacci number? Let nk denote the number of calls
performed in the execution
n0 = 1
n1 = 1
n2 = n1 + n0 + 1 = 3 > 21
n3 = n2 + n1 + 1 = 5 > 22
n4 = n3 + n2 + 1 = 9 > 23
SOME RECURSIVE ALGORITHMS (EXAMPLES) CONTINUOUS
n5 = n4 + n3 + 1 = 15 > 23
...
nk > 2k/2
This means that the Fibonacci recursion makes a number of calls that are
exponential in k. In other words, using binary recursion to compute
Fibonacci numbers is very inefficient. Compare this problem with
binary search, which is very efficient in searching items, why is this
binary recursion inefficient? The main problem with the approach
above, is that there are multiple overlapping recursive calls.
We can compute F(n) much more efficiently using linear recursion. One
way to accomplish this conversion is to define a recursive function that
computes a pair of consecutive Fibonacci numbers F(n) and F(n-1) using
SOME RECURSIVE ALGORITHMS (EXAMPLES) CONTINUOUS
Algorithm LinearFib(n) {
Input: A nonnegative integer n
Output: Pair of Fibonacci numbers (Fn, Fn-1)
if (n <= 1) then
return (n, 0)
else
(i, j) <-- LinearFib(n-1)
return (i + j, i)
}
Since each recursive call to LinearFib decreases the argument n by 1,
the original call results in a series of n-1 additional calls. This
performance is significantly faster than the exponential time needed by
the binary recursion. Therefore, when using binary recursion, we should
first try to fully partition the problem in two or, we should be sure that
overlapping recursive calls are really necessary.
Let's use iteration to generate the Fibonacci numbers. What's the
SOME RECURSIVE ALGORITHMS (EXAMPLES) CONTINUOUS
public static int IterationFib(int n) {
if (n < 2) return n;
int f0 = 0, f1 = 1, f2 = 1;
for (int i = 2; i < n; i++) {
f0 = f1;
f1 = f2;
f2 = f0 + f1;
}
return f2;
}
THANK YOU FOR YOUR AUDIENCE.

You might also like