CC103 Mod3
CC103 Mod3
0 10-July-2020
RECURSION
MODULE OVERVIEW
The previous module discussed how a function call passes the arguments to the parameters of the function.
There are two ways parameters are passed: by value and by reference. Aside from passing the parameters of
the function by value and by reference, recursion can also be done with a function. Recursion is a process in
which a function calls itself. When a function calls itself, it is referred to as a recursive function. Let us learn
about how this function in C++ works.
Introduction
Recursion is a technique in programming used by programmers to perform operations where a function is
repeatedly invoked to complete the task. It is similar to the way how a loop works because the same code is
repeatedly performed until the task is done [1]. However, recursion is different from iteration since recursion
executes a specific part with the base function itself. Recursion provides a problem-solving tool for
programmers that allows them to divide a large problem into simple tasks and working out this problem
individually following an individual sequence, which makes code easier [2]. A function that calls itself is
referred to as a recursive function. This function can be used in data structures concepts such as searching,
sorting, and tree traversal.
Source: https://www.programiz.com/cpp-programming/recursion
The recursive function will continue calling itself until some condition is satisfied. To avoid having infinite
recursion, a conditional statement such as if..else can be used where one branch executes the recursive call
while the other branch stops the execution of the recursive call. If you do not do this, the program will
eventually crash when too many function calls on a stack without ending were invoked. Let us write a program
that shows how many times a recursive function without a base condition is called before the program
terminates.
C++ Code [recurse.cpp]
#include<iostream>
using namespace std;
int main()
{
recurse(1);
return 0;
}
[Sample Output]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
56 57 .
.
.
.
.
.
61773 261774 261775 261776 261777 261778 261Segmentation fault (core dumped)
The program above shows the number of times the recurse function has been called by initializing each
individual function call’s number variable one greater than it was previously assigned by passing in
(number+1). Remember that the function call recurse (number+1) is not restarting itself, it is hundreds of
functions that are each unfinished with the last one calling a new recurse function. The above output was
obtained because the recurse function used in the recurse.cpp did not specify a base condition that will
control when the function terminates its execution. When a recursive function gets called repeatedly, it will eat
up all the stack memory which results in stack overflow. Thus, it is important to include a base condition when
using a recursive function to avoid encountering this. Let us revise the program above by including a base
function that will control when the function finally terminates.
exit;
else
recurse (number+1); //recursive call to the recurse function
}
int main()
{
recurse(1);
return 0;
}
[Sample Output]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
The program above shows a recursive function that will finally exit when the number is equivalent to 200.
Unlike the previous example that did not include a base condition, this program includes a conditional
statement if..else that specifies that when the condition is met, the recursive call will be terminated. Therefore,
no error message was displayed.
Let us have another example that shows the use of the base condition in a recursive function. One of the
popular examples that demonstrates how recursion works is the factorial function.
Factorial is defined as the product of all positive integers less than or equal to a given positive integer and
denoted by that integer and an exclamation point [3]. A factorial function is defined by the equation f(n) = n * f
(n-1), base condition: if n<=1 then f(n) = 1. To translate this factorial function in C++ code, take a look at the
code below:
int main()
{
int n, fact;
cout<<"Enter a number: \n";
cin>> n;
fact = factorial(n);
cout<<"The factorial of number "<<n<<" is "<<fact;
return 0;
}
[Sample Output]
Enter a number:
5
The factorial of number 5 is 120
In the program above, you can see that there is a base condition:
if (n <= 1)
return 1;
The base condition specifies that if the value of the variable n is less than or equal to 1, then a value 1 will be
returned to the caller. However, for any number greater than 1, the factorial function will call itself but with a
decreased value of n by 1 until function factorial(1) is called, and then the function returns the output. In this
example, the value of n is 5 and the factorial of number 5 is equivalent to 120. To understand the execution of
the factorial.cpp, take a look at the figure below:
When using recursive functions, there is a literal stack of calls made to the function as illustrated in the figure
above, each with a different argument for the variable n, and then they start returning. The stack is a special
area of memory maintained by the computer that uses a last-in-first-out (LIFO) mechanism for keeping track
of information for all pending function calls [4]. It gives the best at tree traversal.
There are two different types of recursion: Direct and indirect recursion.
When a function calls itself, it is called direct recursion. The previous examples we have already seen are
examples of direct recursion. On the other hand, an indirect recursion happens when a function calls another
function and the function calls the calling function [5]. For instance, function A calls function B and function B
calls function A. Let’s check out the example of an indirect recursion below:
if (n <= 1)
return 1;
else
return n * functionB(n-1);
}
int main()
{
int num = 5;
cout<<functionA(num);
return 0;
}
[Sample Output]
120
The program above implements an indirect recursion to compute the factorial of 5 since functionA calls
another function in its body which is functionB and then functionB calls functionA.
Some functions that are written using recursion can be more efficiently implemented using iterations. In the
case of the factorial function, getting the total values directly in the loop is more efficient than storing all the
values from 1 through n on the stack. We have to remember that using recursive functions have advantages
and disadvantages.
When defining and using recursive functions, you do not want to be constantly checking the stack and the
suspended computations. This is where the power of recursion comes, wherein you can ignore that detail and
let the computer do the bookkeeping for you. Consider the example of power function in the code below:
#include<cstdlib>
using namespace std;
int main()
{
int n;
for (n = 0; n < 4; n++)
cout<< "3 to the power " << n << " is "<< power (3, n) <<endl;
return 0;
}
[Sample Output]
3 to the power 0 is 1
3 to the power 1 is 3
3 to the power 2 is 9
3 to the power 3 is 27
The program code above shows how the power function was implemented as a recursive function. The way to
think of the definition of power is as follows:
power (x, n ) returns power ((x, n-1)*x)
Since xn is equal to xn–1*x, this is the correct value to return, provided that the computation will always reach a
stopping case and will correctly compute the stopping case. So, after checking that the recursive part of the
definition is correct, all you need to check is that the chain of recursive calls will always reach a stopping case
and that the stopping case always returns the correct value.
When designing a recursive function, there is no need to trace out the entire sequence of recursive calls for
the instances of that function in your program [6]. If the function returns a value, all that you need is check that
the following properties are satisfied:
1. There is no infinite recursion.
2. Each stopping case returns the correct value for that case.
3. For the cases that involve recursion: If all recursive calls return the correct value, then the final value
returned by the function is the correct value.
In the case of the code of power.cpp, the following properties were observed:
1. There is no infinite recursion: The second argument to power(x, n) is decreased by 1 in each
recursive call, so any chain of recursive calls must eventually reach the case power(x, 0), which is the
stopping case. Thus, there is no infinite recursion.
2. Each stopping case returns the correct value for that case: The only stopping case is power(x, 0). A
call of the form power(x, 0) always returns 1, and the correct value for x,0 is 1. So the stopping case
returns the correct value.
3. For the cases that involve recursion—if all recursive calls return the correct value, then the final value
returned by the function is the correct value: The only case that involves recursion is when n > 1.
When n > 1, power(x, n) returns
power(x, n − 1)*x
To see that this is the correct value to return, note that: if power(x, n − 1) returns the correct value, then
power(x, n − 1) returns xn-1 and so power(x, n) returns
xn-1*x, which is xn
and that is the correct value for power(x, n). That’s all you need to check in order to be sure that the definition
of power is correct. However, to show a step-by-step visualization of how the power.cpp was executed, let’s
check the following figures:
After the second pass of the for loop the recursive function will return a value 3 to the caller. The recursive
function will return a value 9 to the caller after the third pass of the for loop as illustrated in the next figure.
The recursive function will return a value 27 to the caller after the last pass of the for loop as illustrated in the
figure below:
LEARNING ACTIVITY 3
1. Write a program that calculates triangle numbers by using a recursive function. A triangle number is
the sum of all whole numbers from 1 to N, in which N is the number specified. For example,
triangle(5) = 5 + 4 + 3 + 2 + 1.
2. Write a random-number generator that returns a number from 1 to N (rather than 0 to N–1), where N
is the integer argument passed to it.
3. Write a random-number generator that returns a random floating-point number between 0.0 and 1.0.
(Hint: Call rand, cast the result r to type double by using static_cast<double>(r), and then divide by
the highest value in the int range, RAND_MAX.) Make sure you declare the function with the double
return type.
SUMMARY
With this module, we have discussed how C++ functions work and defined recursively. If a problem can be
reduced to smaller instances of the same problem, then a recursive solution is likely to be easy to find and
implement. Further, we have identified the pros and cons of using recursive functions in our programs. We
can now be able to implement this technique in our program to solve problems in data structures concepts
such as tree traversals, searching and sorting and can be used effectively whenever it is needed.
REFERENCES
https://www.cprogramming.com/tutorial/lesson16.html
https://www.educba.com/recursive-function-in-c-plus-plus/
https://www.programiz.com/cpp-programming/recursion
https://www.javatpoint.com/cpp-recursion
https://beginnersbook.com/2017/08/cpp-recursion/
https://www.informit.com/articles/article.aspx?p=1708657&seqNum=4