Recursion 1.
Recursion 1.
Group: 652.21E
Specialty:Computer engineering
Topic: Recursion
Plan Recursive functions and algorithms
01
04 Tail-recursive functions
A common algorithm design tactic is to
divide a problem into sub-problems of the
same type as the original, solve those
sub-problems, and combine the results.
This is often referred to as the divide-and-
conquer method; when combined with
a lookup table that stores the results of
previously solved sub-problems (to avoid
solving them repeatedly and incurring
extra computation time), it can be referred
to as dynamic
programming or memoization.
A recursive function definition has one or more base
cases, meaning input(s) for which the function produces a
result trivially (without recurring), and one or more recursive
cases, meaning input(s) for which the program recurs (calls
itself).
For example, the factorial function can be
defined recursively by the equations 0! =
1 and, for all n > 0, n! = n(n − 1)!. Neither
The job of the recursive cases can be seen as
breaking down complex inputs into simpler ones. In a
equation by itself constitutes a complete properly designed recursive function, with each
definition; the first is the base case, and the recursive call, the input problem must be simplified in
second is the recursive case. such a way that eventually the base case must be
Base Case
reached.
Because the base case breaks the For some functions (such as one that computes
the series for e = 1/0! + 1/1! + 1/2! + 1/3! + ...)
chain of recursion, it is sometimes
there is not an obvious base case implied by the
also called the "terminating case". input data; for these one may add
a parameter (such as the number of terms to be
added, in our series example) to provide a
'stopping criterion' that establishes the base
case.
As a first example, let's write a
function pow(x, n) that raises x to
the natural power of n. In other
words, it multiplies x by itself n
times.
Consider two ways to implement it.
1.pow(2, 4) = 2 * pow(2, 3)
2.pow(2, 3) = 2 * pow(2, 2)
3.pow(2, 2) = 2 * pow(2, 1)
4.pow(2, 1) = 2
Recursion versus iteration
Tail-recursive functions are functions in which all recursive calls are tail calls and hence do not build up
any deferred operations. For example, the gcd function (shown again below) is tail-recursive. In contrast,
the factorial function (also below) is not tail-recursive; because its recursive call is not in tail position, it
builds up deferred multiplication operations that must be performed after the final recursive call
completes. With a compiler or interpreter that treats tail-recursive calls as jumps rather than function calls,
a tail-recursive function such as gcd will execute using constant space. Thus the program is essentially
iterative, equivalent to using imperative language control structures like the "for" and "while" loops.
The significance of tail recursion is that when making a tail-recursive call (or
any tail 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, in languages that recognize this property of tail calls,
tail recursion saves both space and time.
Thank you for your
attention