0% found this document useful (0 votes)
60 views26 pages

Lecture No 3: CS-302 Design and Analysis of Algorithms

The document discusses recursion, which is a problem-solving technique where a function calls itself to solve smaller instances of the same problem. It provides examples of recursive data structures like linked lists and trees, as well as recursive algorithms like calculating factorials and Fibonacci numbers. The key aspects of recursion are that it divides a problem into sub-problems until reaching a base case that can be solved directly, and that each recursive call relies on the solution to the previous call.

Uploaded by

Tanveer Zafar
Copyright
© Attribution Non-Commercial (BY-NC)
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)
60 views26 pages

Lecture No 3: CS-302 Design and Analysis of Algorithms

The document discusses recursion, which is a problem-solving technique where a function calls itself to solve smaller instances of the same problem. It provides examples of recursive data structures like linked lists and trees, as well as recursive algorithms like calculating factorials and Fibonacci numbers. The key aspects of recursion are that it divides a problem into sub-problems until reaching a base case that can be solved directly, and that each recursive call relies on the solution to the previous call.

Uploaded by

Tanveer Zafar
Copyright
© Attribution Non-Commercial (BY-NC)
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/ 26

Lecture No 3

CS-302 Design and Analysis of Algorithms


Recursion
• Basic problem solving technique is to divide a
problem into smaller sub-problems
• These sub-problems may also be divided into
smaller sub-problems
• When the sub-problems are small enough to
solve directly the process stops
• A recursive algorithm is a problem solution
that has been expressed in terms of two or
more easier to solve sub-problems
What is recursion?
• A procedure that is defined in terms of itself
• In a computer language a function that calls
itself
Recursion
A recursive definition is one which is defined in terms of itself.

Examples:

• A phrase is a "palindrome" if the 1st and last letters are the same,
and what's inside is itself a palindrome (or empty or a single letter)

• Rotor

• Rotator

• 12344321
Recursion

• The definition of the natural numbers:


1 is a natural number
N=
if n is a natural number, then n+1 is a natural number
Recursion in Computer Science
1. Recursive data structure: A data structure that is partially
composed of smaller or simpler instances of the same data
structure.

For instance, a tree is composed of smaller trees (subtrees) and leaf


nodes, and a list may have other lists as elements.
a data structure may contain a pointer to a variable of the same type:
struct Node {
int data;
Node *next;
};
• Recursive procedure: a procedure that invokes
itself

• Recursive definitions: if A and B are postfix


expressions, then A B + is a postfix expression.
Recursive Data Structures
Linked lists and trees are recursive data structures:
struct Node {
int data;
Node *next;
};

struct TreeNode {
int data;
TreeNode *left;
TreeNode * right;
};

Recursive data structures suggest recursive algorithms.


A mathematical look
• We are familiar with
f(x) = 3x+5
• How about
f(x) = 3x+5 if x > 10 or
f(x) = f(x+2) -3 otherwise
Calculate f(5)
f(x) = 3x+5 if x > 10 or
f(x) = f(x+2) -3 otherwise

f(5) = f(7)-3
f(7) = f(9)-3
f(9) = f(11)-3
f(11) = 3(11)+5
= 38
But we have not determined what f(5) is yet!
Calculate f(5)
f(x) = 3x+5 if x > 10 or
f(x) = f(x+2) -3 otherwise

f(5) = f(7)-3 = 29
f(7) = f(9)-3 = 32
f(9) = f(11)-3 = 35
f(11) = 3(11)+5
= 38
Working backwards we see that f(5)=29
Series of calls

f(5)

f(7)

f(9)

f(11)
Recursion
Recursion occurs when a function/procedure calls itself.

Many algorithms can be best described in terms of recursion.

Example: Factorial function


The product of the positive integers from 1 to n inclusive is
called "n factorial", usually denoted by n!:

n! = 1 * 2 * 3 .... (n-2) * (n-1) * n


Recursive Definition
of the Factorial Function

1, if n = 0
n! =
n * (n-1)! if n > 0

5! = 5 * 4! = 5 * 24 = 120
4! = 4 * 3! = 4 * 3! = 4 * 6 = 24
3! = 3 * 2! = 3 * 2! = 3 * 2 = 6
2! = 2 * 1! = 2 * 1! = 2 * 1 = 2
1! = 1 * 0! = 1 * 0! = 1
Recursive Definition
of the Fibonacci Sequence

The Fibonacci numbers are a series of numbers as follows:

fib(1) = 1 1, n <= 2
fib(2) = 1 fib(n) = fib(n-1) + fib(n-2), n > 2
fib(3) = 2
fib(4) = 3
fib(5) = 5
... fib(3) = 1 + 1 = 2
fib(4) = 2 + 1 = 3
fib(5) = 2 + 3 = 5
Recursive Definition

int BadFactorial(n){
int x = BadFactorial(n-1);
if (n == 1)
return 1;
else
return n*x;
}
What is the value of BadFactorial(2)?

We must make sure that recursion eventually stops, otherwise


it runs forever:
Using Recursion Properly
For correct recursion we need two parts:

1. One (ore more) base cases that are not recursive, i.e. we
can directly give a solution:
if (n==1)
return 1;

2. One (or more) recursive cases that operate on smaller


problems that get closer to the base case(s)
return n * factorial(n-1);

The base case(s) should always be checked before the recursive


calls.
Counting Digits
• Recursive definition
digits(n) = 1 if (–9 <= n <= 9)
1 + digits(n/10) otherwise
• Example
digits(321) =
1 + digits(321/10) = 1 +digits(32) =
1 + [1 + digits(32/10)] = 1 + [1 + digits(3)] =
1 + [1 + (1)] =
3
Counting Digits in C++

int numberofDigits(int n) {
if ((-10 < n) && (n < 10))
return 1
else
return 1 +
numberofDigits(n/10);
}
Recursion
• If you want to compute f(x) but can’t compute
it directly
• Assume you can compute f(y) for any value of
y smaller than x
• Use f(y) to compute f(x)
• For this to work, there has to be at least one
value of x for which f(x) can be computed
directly (e.g. these are called base cases)
Evaluating Exponents Recurisivley

int power(int k, int n) {


// raise k to the power n
if (n == 0)
return 1;
else
return k * power(k, n – 1);
}
Divide and Conquer
• Using this method each recursive subproblem is
about one-half the size of the original problem
• If we could define power so that each
subproblem was based on computing kn/2
instead of kn – 1 we could use the divide and
conquer principle
• Recursive divide and conquer algorithms are
often more efficient than iterative algorithms
Evaluating Exponents Using Divide and
Conquer

int power(int k, int n) {


// raise k to the power n
if (n == 0)
return 1;
else{
int t = power(k, n/2);
if ((n % 2) == 0)
return t * t;
else
return k * t * t;
}
Stacks
• Every recursive function can be implemented
using a stack and iteration.
• Every iterative function which uses a stack can
be implemented using recursion.
Disadvantages
• May run slower.
– Compilers
– Inefficient Code

• May use more space.


Advantages
• More natural.
• Easier to prove correct.
• Easier to analysis.
• More flexible.

You might also like