The trick with recursion is that there are several things you are keeping track of:
1 - the return value. This can be combined by using some operation between a value and another invocation, or by passing a modified version of it as argument to the invocation.
2 - the control arguments. This is how you keep track of what is happening.
Here is a loop that prints 1 to 10:
1 2
|
for (int n = 1; n <= 10; ++n)
cout << n << endl;
|
Recursively, there is no result, and the control argument is the number n:
1 2 3 4 5 6
|
void print_range( int n, int max_n )
{
cout << n << endl;
if (n < max_n)
print_range( ++n, max_n );
}
|
When you want to create something, like a list, it helps to have an argument to keep it:
1 2 3
|
vector <int> ns;
for (int n = 1; n <= 10; ++n)
ns.push_back( n );
|
Recursively:
1 2 3 4 5 6
|
void generate_range( int n, int max_n, vector <int> & ns )
{
ns.push_back( n );
if (n < max_n)
generate_range( ++n, max_n, ns );
}
|
1 2
|
vector <int> ns;
generate_range( 1, 10, ns );
|
This last example shows something. There are
two objects named 'ns': the one that the function works on, and the reference argument. I could, conceivably, made 'ns' global and just referred to it directly, but by using a reference argument I can modify any vector I want.
The other way is by modifying it -- directly through return values -- is tricky. You have to keep in mind exactly when a thing is modified, and how to modify it properly. I recommend you avoid it for now and stick with reference arguments.
This last function is called a 'generator', because it creates a thing.
Another type is called a 'consumer', because it eats something up:
1 2 3 4
|
int sum = 0;
int values[] = { 1, 2, 3, 4, 5, 6, 7 };
for (int n = 0; n < 7; ++n)
sum += values[ n ];
|
Recursively:
1 2 3 4 5 6 7
|
int sum_list( int n, int size, int* values )
{
if (n < size)
return values[ n ] + sum_list( n + 1, size, values );
else
return 0;
}
|
1 2
|
int values[] = { 1, 2, 3, 4, 5, 6, 7 };
int sum = sum_list( 0, 7, values );
|
Hopefully you should be able to get your head around this one if you followed the last two. So long as the index into the list ('n') is less than the size of the list (the same thing we do in the loop), we add the indexed element into the result, and add the sum of the
remainder of the list.
Hence, we are really saying:
sum = (1 + (2 + (3 + (4 + (5 + (6 + (7 + 0))))))));
One last thing to notice: when using recursion we often have to have a lot more arguments to our functions than we would think we would. (In actuality, we use the same arguments in our loops, but since we only say them once, it seems odd to have to repeat them over and over in the recursion.)
Well, I hope this helps somewhat.