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

Recursion: Programming Technique in Which A Method (Function) Calls Itself

The document discusses recursion, which is a programming technique where a method calls itself. It provides examples of recursively calculating triangular numbers and factorials. Recursion simplifies problems conceptually but is less efficient than iteration due to overhead from method calls and potential for stack overflows. The document also covers binary search and quicksort algorithms implemented recursively and iteratively.

Uploaded by

Romeo Balingao
Copyright
© © All Rights Reserved
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
33 views

Recursion: Programming Technique in Which A Method (Function) Calls Itself

The document discusses recursion, which is a programming technique where a method calls itself. It provides examples of recursively calculating triangular numbers and factorials. Recursion simplifies problems conceptually but is less efficient than iteration due to overhead from method calls and potential for stack overflows. The document also covers binary search and quicksort algorithms implemented recursively and iteratively.

Uploaded by

Romeo Balingao
Copyright
© © All Rights Reserved
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 23

Recursion

Programming technique in which a


method (function) calls itself
Triangular Numbers
What is x in the series?
1, 3, 6, 10, 15, 21, x
Also called triangular numbers

#1 = 1 #2 = 3 #3 = 6
#4 = 10
and so on
Triangular Numbers
Suppose you wanted to find the value of
some arbitrary n-th term in the series; say
the 4
th
term (whose value is 10). How
would you calculate it?
Triangular Numbers
You might decide that the value of any term
can be obtained by adding up all the vertical
columns of squares
4 + 3 + 2 + 1 = 10
Procedural Programming
int triangle(int n)
{
int total = 0

while(n > 0) // until n is 1
{
total = total + n; // add n (column height) to total
--n; // decrement column height
}
return total
}
Recursive Programming
The value of the n-th term can be thought
of as the sum of only 2 things, instead of a
whole series. These are:
1. The first (tallest) column, which has the value n
2. The sum of all the remaining columns
4 + 6 in the remaining columns = 10
Recursive Programming
int triangle (int n)
{
return (n + sumRemainingColumns(n));
}
If we knew a method that found the sum of
all remaining columns:
Recursive Programming
int triangle (int n)
{
return (n + SumAllColumns(n-1));
}
sumRemainingColumns (n) = sumAllColumns(n-1)
Recursive Programming
sumAllColumns( ) = triangle ( )
int triangle (int n)
{
return (n + triangle(n-1));
}
Recursion : Passing the Buck
Someone tells me to find the 4
th
triangular number
I know this is 4 plus the 3
rd
triangular number
I call Harry and ask him to find the 3
rd
triangular number
Harry knows that the 3
rd
triangular number is 3 plus the 2
nd

triangular number
Harry calls Jane and asks her to find the 2
nd
triangular number
Jane knows that the 2
nd
triangular number is 2 plus the 1
st

triangular number (which is 1)
The buck-passing must end at some point. Otherwise, the
method would call itself over and over in an infinite series that
would paralyse the program
The Buck Stops Here
The person who is asked to find the 1
st
triangular number
(when n = 1), must know the answer without asking
anyone else. He knows the answer is 1.
Every recursive method must have a base case to prevent
infinite recursion
int triangle (int n)
{
if(n == 1) // base case
return 1;
else
return (n + triangle(n-1));
}
Trace the output of the following program
int triangle (int n)
{
System.out.println (Entering: n= + n);
if(n == 1) {
System.out.println (Returning 1);
return 1;
}
else {
int temp = n + triangle(n-1);
System.out.println(Returning + temp);
return temp
}
}
Whats really happening?
Each time the triangle( ) method calls itself, its argument,
which starts at 4, is reduced by 1.
The method plunges down into itself again again until its
argument is reduced to 1. Then it returns.
This triggers an entire series of returns.
The method rises back up, phoenix-like, out of the
discarded versions of itself.
Each time it returns it adds the value of n it was called with
to the return value from the method it called.
Note: Just before the innermost version returns a 1, there
are actually 4 different incarnations of triangle( ) in
existence at the same time.
Characteristics of recursive methods
It calls itself
When it calls itself, it does so to solve a smaller problem
Theres some version of the problem that is simple enough
that the routine can solve it, and return, without calling
itself.
int triangle (int n)
{
if(n == 1) // base case
return 1;
else
return (n + triangle(n-1));
}
Is recursion efficient?
Method calling involves some overhead
Control must be transferred to and fro, with each call
having its own set of arguments utilising a stack so that
the method can access the argument values and know
where to return
Memory usage may cause stack overflow
Recursive computer programs require more memory and
computation compared with iterative algorithms, but they
are simpler and for many cases a natural way of thinking
about the problem.
Recursion is usually used because it simplifies a problem
conceptually, not because its inherently more efficient
Factorials
Similar to triangular number, except that:
multiplication is the arithmetic operator, not
addition
factorial(0) = 1, factorial(1) = 1*1 = 1,
factorial(2) = 1*2 = 2, factorial(3) = 3*2 = 6
and so on

Factorials
int factorial (int n)
{
if(n == 0) // base case
return 1;
else
return (n * factorial(n-1));
}
Find the n-th even number
Procedural Method

Algorithm -> Even(positive integer k)
Input: k, a positive integer
Output: k-th even natural number (the first even being 0)

Algorithm:
int i, even;
i := 1;
even := 0;
while( i <k ) {
even := even + 2;
i := i + 1;
}
return even .
Recursive Algorithm
Procedural Binary Search
public int find(double searchKey)
{
int lowerBound = 0;
int upperBound = nElems-1;
int curIn;

while(true)
{
curIn = (lowerBound + upperBound ) / 2;
if(a[curIn]==searchKey)
return curIn; // found it
else if(lowerBound > upperBound)
return nElems; // can't find it
else // divide range
{
if(a[curIn] < searchKey)
lowerBound = curIn + 1; // it's in upper half
else
upperBound = curIn - 1; // it's in lower half
} // end else divide range
} // end while
} // end find()
Recursive Binary Search
public int find(double searchKey)
{
return recFind(searchKey, 0, nElems-1);
}
//-----------------------------------------------------------
private int recFind(double searchKey, int lowerBound,
int upperBound)
{
int curIn;

curIn = (lowerBound + upperBound ) / 2;
if(a[curIn]==searchKey)
return curIn; // found it
else if(lowerBound > upperBound)
return nElems; // can't find it
else // divide range
{
if(a[curIn] < searchKey) // it's in upper half
return recFind(searchKey, curIn+1, upperBound);
else // it's in lower half
return recFind(searchKey, lowerBound, curIn-1);
} // end else divide range
} // end recFind()
Partition Algorithm
Partition Algorithm
public int partitionIt(int left, int right, double pivot)
{
int leftPtr = left - 1; // right of first elem
int rightPtr = right + 1; // left of pivot
while(true)
{
while(leftPtr < right && // find bigger item
theArray[++leftPtr] < pivot)
; // (nop)

while(rightPtr > left && // find smaller item
theArray[--rightPtr] > pivot)
; // (nop)
if(leftPtr >= rightPtr) // if pointers cross,
break; // partition done
else // not crossed, so
swap(leftPtr, rightPtr); // swap elements
} // end while(true)
return leftPtr; // return partition
} // end partitionIt()

You might also like