How to understand function recursion precisely? - c++

I am currently programming some divide-conquer algorithms, where function recursions are used everywhere, but I have very vague idea or no idea how exactly it works, and that's why I post it here and hope you don't mind it's too basic.
For example, if we have the following code:
#include<iostream>
using namespace std;
void Recursion(int n)
{
cout << n << endl;
if(n > 0)
{
Recursion(n-1);
}
cout<<n<<endl;
}
int main()
{
Recursion(3);
return 0;
}
I tested Recursion(3) and the print out in the terminal is:
3
2
1
0
0
1
2
3
I can understand the concept of recursive call of the function but I don't understand the mechenism how it works. For example, what will they do after they can't call the function again? For example, here, I can understand it prints from 3 to 0 but why it also prints from 0 to 3 again? I heard it's because function recursion is stored in a stack for one recursion and when it reaches the "bottom" it also has to delete.
But anyway, I don't know about it. So, can anyone help me out and clearly tell me what happened here and the exact flow of function call?
Thanks for your help!

The key to understanding recursion is the concept of the call stack. The call stack consists of "frames". A stack frame contains a function's local variables and an invisible return address. The classic physical analogy is a stack of plates. When you make a function call a plate (stack frame) is added to the top of the stack. When you return from a function the top plate (stack frame) is removed. You can only use the plate (stack frame) that is on top.
Recursive functions work the same way as ordinary functions. They are a little tricky because you can have multiple instances of their local variables on the stack at a given time. However, like other functions the function only refers to the stack frame that is on the top of the stack.
To illustrate how this works let's walk through your program showing how the call stack grows and shrinks.
Let's start with the base case: 0. Recursion(0);
Enter main: The stack is empty: Bottom of stack->||<-Top of stack
Recursion(0); Enter Recursion the stack has grown: Bottom of stack->|0|<-Top of stack
cout << n << endl; The value of n is 0 so the output is "0"
if (n > 0). 0 is not greater than 0 so Recursion(-1) is not called.
cout << n << endl; The value of n is 0 so the output is "0"
Return to main() the stack is empty again: Bottom of stack->||<-Top of stack
The output would be
0
0
Simple enough, no recursion took place. Let's take the next step. Recursion(1);
Enter main: Bottom of stack->||<-The top of stack
Recursion(1); Enter Recursion: Bottom of stack->|1|<-Top of stack
cout << n << endl; The value of n is 1 so the output is "1"
if (n > 0). 1 is greater than 0 so Recursion(0); is called.
Enter Recursion: Bottom of stack->|1,0|<-Top of stack
cout << n << endl; The value of n in this stack frame is 0 so the output is "0"
if (n > 0). 0 is not greater than 0 so the function does not recurse.
cout << n << endl; The value of n is 0 so the output is "0"
Return to the first call to Recursion. Bottom of stack->|1|<-Top of stack
cout << n << endl; The value of n is 1 so the output is "1"
Output
1
0
0
1
Let's go through the execution one final time with n == 2
Enter main: Bottom->||<-Top
Recursion(2); Enter Recursion: Bottom->|2|<-Top
cout << n << endl; "2"
if (n > 0). 2 is greater than 0 so Recursion(1); is called.
Enter Recursion: Bottom->|2,1|<-Top
cout << n << endl; "1"
if (n > 0). 1 is greater than 0 so Recursion(0); is called.
Enter Recursion: Bottom->|2,1,0|<-Top
cout << n << endl; "0"
if (n > 0). 0 is not greater than 0 so the function does not recurse again.
cout << n << endl; "0"
Return. Bottom->|2,1|<-Top
cout << n << endl; "1"
Return. Bottom->|2|<-Top
cout << n << endl; "2"
Return to main(). Bottom->||<-Top
Output
2
1
0
0
1
2

You are right, I also find recursive functions difficult to understand. Here is what i do, if i see a recursive function: run all the code step by step in your mind. This advice may seem trivial, but most of the time it works for me. Let's look at your code:
You call Recursion() function with parameter 3. It prints n and n>0 that's why it calls Recursion(2) (note that we didn't return from the Recursion(3) call we are still in it and now we are also in Recursion(2). The same is for recursion(1) and 0. Now n>0 conditional is false. It prints 0. and we return from recursion(0) We print 1 and return from recursion(1) and it goes on the recursion(3)
Recursion(3)
Recursion(2)
Recursion(1)
Recursion(0)
return from Recursion(0)
return from Recursion(1)
return from Recursion(2)
return from Recursion(3)

A function calling itself is not different from a function calling another function: before proceeding it has to wait that the function it has called returns.
By the way, recursion might look elegant, but in general it's not the most efficient way of programming: it makes for example impossible to inline functions, so the overhead for context switch is guaranteed. There's always a more efficient way to obtain the same result of a recursive function. But for some problems a recursive implementation is more intuitive, and not slower in any significant way. The example you gave in the comments, merge sort, is a good one.
A couple of interesting discussion about this:
Way to go from recursion to iteration
Can every recursion be converted into iteration?
My final advice: do not go for recursive when the problem does not require this approach, for example when computing a factorial.

Sometimes it is easier to understand recursion by starting at the base case, that is, the one that does not recurse.
In your example, when n<=0, the call is resolved without more calls. Let's start by that.
If you call Recursion(0), the expected result is to print zero twice, one before and one after the if. The code inside the if does not execute.
Now, Recursion(1) does its first print of the value one, then calls Recursion(0) which in its turn prints 0 twice like before, then execution returns to Recursion(1), which prints 1 again, after the execution of Recursion(0). That is why you see 1 0 0 1.
The same applies to Recursion(2), which will wrap the result of Recursion(1) around twos.

Related

What happens when we call a function after initial condition [duplicate]

I am currently programming some divide-conquer algorithms, where function recursions are used everywhere, but I have very vague idea or no idea how exactly it works, and that's why I post it here and hope you don't mind it's too basic.
For example, if we have the following code:
#include<iostream>
using namespace std;
void Recursion(int n)
{
cout << n << endl;
if(n > 0)
{
Recursion(n-1);
}
cout<<n<<endl;
}
int main()
{
Recursion(3);
return 0;
}
I tested Recursion(3) and the print out in the terminal is:
3
2
1
0
0
1
2
3
I can understand the concept of recursive call of the function but I don't understand the mechenism how it works. For example, what will they do after they can't call the function again? For example, here, I can understand it prints from 3 to 0 but why it also prints from 0 to 3 again? I heard it's because function recursion is stored in a stack for one recursion and when it reaches the "bottom" it also has to delete.
But anyway, I don't know about it. So, can anyone help me out and clearly tell me what happened here and the exact flow of function call?
Thanks for your help!
The key to understanding recursion is the concept of the call stack. The call stack consists of "frames". A stack frame contains a function's local variables and an invisible return address. The classic physical analogy is a stack of plates. When you make a function call a plate (stack frame) is added to the top of the stack. When you return from a function the top plate (stack frame) is removed. You can only use the plate (stack frame) that is on top.
Recursive functions work the same way as ordinary functions. They are a little tricky because you can have multiple instances of their local variables on the stack at a given time. However, like other functions the function only refers to the stack frame that is on the top of the stack.
To illustrate how this works let's walk through your program showing how the call stack grows and shrinks.
Let's start with the base case: 0. Recursion(0);
Enter main: The stack is empty: Bottom of stack->||<-Top of stack
Recursion(0); Enter Recursion the stack has grown: Bottom of stack->|0|<-Top of stack
cout << n << endl; The value of n is 0 so the output is "0"
if (n > 0). 0 is not greater than 0 so Recursion(-1) is not called.
cout << n << endl; The value of n is 0 so the output is "0"
Return to main() the stack is empty again: Bottom of stack->||<-Top of stack
The output would be
0
0
Simple enough, no recursion took place. Let's take the next step. Recursion(1);
Enter main: Bottom of stack->||<-The top of stack
Recursion(1); Enter Recursion: Bottom of stack->|1|<-Top of stack
cout << n << endl; The value of n is 1 so the output is "1"
if (n > 0). 1 is greater than 0 so Recursion(0); is called.
Enter Recursion: Bottom of stack->|1,0|<-Top of stack
cout << n << endl; The value of n in this stack frame is 0 so the output is "0"
if (n > 0). 0 is not greater than 0 so the function does not recurse.
cout << n << endl; The value of n is 0 so the output is "0"
Return to the first call to Recursion. Bottom of stack->|1|<-Top of stack
cout << n << endl; The value of n is 1 so the output is "1"
Output
1
0
0
1
Let's go through the execution one final time with n == 2
Enter main: Bottom->||<-Top
Recursion(2); Enter Recursion: Bottom->|2|<-Top
cout << n << endl; "2"
if (n > 0). 2 is greater than 0 so Recursion(1); is called.
Enter Recursion: Bottom->|2,1|<-Top
cout << n << endl; "1"
if (n > 0). 1 is greater than 0 so Recursion(0); is called.
Enter Recursion: Bottom->|2,1,0|<-Top
cout << n << endl; "0"
if (n > 0). 0 is not greater than 0 so the function does not recurse again.
cout << n << endl; "0"
Return. Bottom->|2,1|<-Top
cout << n << endl; "1"
Return. Bottom->|2|<-Top
cout << n << endl; "2"
Return to main(). Bottom->||<-Top
Output
2
1
0
0
1
2
You are right, I also find recursive functions difficult to understand. Here is what i do, if i see a recursive function: run all the code step by step in your mind. This advice may seem trivial, but most of the time it works for me. Let's look at your code:
You call Recursion() function with parameter 3. It prints n and n>0 that's why it calls Recursion(2) (note that we didn't return from the Recursion(3) call we are still in it and now we are also in Recursion(2). The same is for recursion(1) and 0. Now n>0 conditional is false. It prints 0. and we return from recursion(0) We print 1 and return from recursion(1) and it goes on the recursion(3)
Recursion(3)
Recursion(2)
Recursion(1)
Recursion(0)
return from Recursion(0)
return from Recursion(1)
return from Recursion(2)
return from Recursion(3)
A function calling itself is not different from a function calling another function: before proceeding it has to wait that the function it has called returns.
By the way, recursion might look elegant, but in general it's not the most efficient way of programming: it makes for example impossible to inline functions, so the overhead for context switch is guaranteed. There's always a more efficient way to obtain the same result of a recursive function. But for some problems a recursive implementation is more intuitive, and not slower in any significant way. The example you gave in the comments, merge sort, is a good one.
A couple of interesting discussion about this:
Way to go from recursion to iteration
Can every recursion be converted into iteration?
My final advice: do not go for recursive when the problem does not require this approach, for example when computing a factorial.
Sometimes it is easier to understand recursion by starting at the base case, that is, the one that does not recurse.
In your example, when n<=0, the call is resolved without more calls. Let's start by that.
If you call Recursion(0), the expected result is to print zero twice, one before and one after the if. The code inside the if does not execute.
Now, Recursion(1) does its first print of the value one, then calls Recursion(0) which in its turn prints 0 twice like before, then execution returns to Recursion(1), which prints 1 again, after the execution of Recursion(0). That is why you see 1 0 0 1.
The same applies to Recursion(2), which will wrap the result of Recursion(1) around twos.

Can't understand this Recursive Function

How is this giving the output from 1 to 10? Shouldn't the output be 0 ?
While debugging i can see that the cout is called serveral times at the end but where is the addition being performed at ?
#include <iostream>
using namespace std;
void func(int n);
int main()
{
func(10);
return 0;
}
void func(int n)
{
if (n <= 0)
return;
else
func(n - 1);
cout << n << endl;
}
Output
Whenever you call a function, you are pushing its stack frame onto the call stack. The stack frame consists of the function parameters, its local variables, and its return address. When you initially call func(), you pass in a value of 10, and then inside func(), you call func() again with 9. You continue calling func() with n-1 until you reach 0, at which point you return. Your call stack will look something like
frame containing 1
frame containing 2
...
frame containing 10
The stack will then "unwind", starting at the top and working down. Each function in the stack will begin where it left off, which is cout, and so each value will be printed out as the stack unwinds.
I'd recommend reading up on the call stack to learn more.
Alright, I'll walk you through it. We've all struggled with programming in the beginning so I don't mind helping.
func(10) is called
10 is greater than 0
func(9) is called
9 is greater than 0
etc...
func(1) is called
1 is greater than 0
func(0) is called
0 ==0
return
After the function returns, it calls every cout statement on the way back up to 10, because the function couldn't call it until all the func calls had eventually returned or reached the end of the function
So on the way out, it outputs 1,2,3,4....10
So basically the recursive function keeps calling itself until it returns the value. So if you did func(2) it checks that 2 <= 0 then calls func(2-1) not printing until this new call completes. Then it checks if 2-1 <= 0, calls func(1-1), still not printing till the new function finishes. Now it sees that 1-1 is <= 0 so it returns 0. Now the previous function call can continue and it prints 2-1 = 1. Then the previous previous function can continue and it prints 2. Hope that makes sense.

recursively print n, n-1, n-2,...3,2,1,2,3,...n

Hello I have a homework question I am stuck in..any hint or tips would be appreciated. the questions is:
Write a single recursive function in C++ that takes as argument a positive integer n then print n, n-1, n-2,...3,2,1,2,3,...n. How many recursive call does your algorithm makes? What is the worst case running time of your algorithm?
I am stuck in the first part. writing a recursive function that prints n, n-1, n-2,...3,2,1,2,3,...n
so far I have:
print(int n)
{
if (n==0)
return;
cout<<n<<" ";
print(n-1);
return;
}
but this only prints from n to 1
I am lost about how I would print from 2 to n using just one parameter and recursively single function.
I tried this: which gives the correct output but has a loop and has two parameters:
p and z has the same value.
void print(int p,int z)
{
if (p==0)
{
for(int x=2;x<=z; x++)
cout<<x<<" ";
return;
}
else
cout<<p<<" ";
print(p-1,z);
return;
}
any hint or tips is much appreciated thank you.
so it is working now, but I am having trouble understanding how (question in comment):
void print(int n)
{
if (n==1){
cout<<n;
return;
}
else
cout<< n;
print(n-1); // how does it get passed this? to the line below?
cout<<n; // print(n-1) takes it back to the top?
return;
}
The output you want is mirrored, so you can have this series of steps:
print num
recursive step on num-1
print num again
That's the recursive case. Now you need an appropriate base case upon which to stop the recursion, which shouldn't be difficult.
Given the pseudocode:
recursive_print(n):
if n == 1:
print 1
return
print n
recursive_print(n-1)
print n
(If you prefer, just look at your solution instead).
Let's trace it. A dot will mark where we're up to in terms of printing.
. recursive_print(3) // Haven't printed anything
3 . recursive_print(2) 3 // Print the 3
3 2 . recursive_print(1) 2 3 //Print 2
3 2 1 . 2 3 // Print 1
3 2 1 2 . 3 // Print 2
3 2 1 2 3 . // Print 3
Each unrolling of the function gives us 2 numbers on opposite sides and we build down to the "1", then go back and print the rest of the numbers.
The "unrolling" is shown in this picture:
If you strip away the functions and leave yourself with a sequence of commands, you'll get:
print 3
print 2
print 1
print 2
print 3
where each indentation signifies a different function.
Simple solution for this:
Def fxn(n):
if n <= n:
if n > 0:
print(n)
fxn(n - 1)
print(n)
Def main():
Number = 6
fxn(Number)
Main()
If you struggle understanding how this works:
Basically, each time you call a function in a recursive problem, it isn't a loop. It's as if you were on the woods leaving a trail behind. Each time you call a function inside a function, it does its thing, then it goes right back to were you called it.
In other words, whenever you call a recursive function, once the newer attempt is done, it will go right back to were it used to be.
In loops, once each step is done, it is done, but in recursive functions you can do a lot with a lot less.
Printing before the recurse call in my code is the descension step, and once its descension finished, it will progresively unfold step by step, printing the ascension value and going back to the former recurse.
It seems way harder than it is, but it is really easy once you grasp it.
The answer is simpler than you think.
A recursive call is no different from a regular call. The only difference is that the function called is also the caller, so you need to make sure you don't call it forever (you already did that). Let's think about a regular call. If you have the following code snippet:
statement1
f();
statement2
The statement1 is executed, then f is called and does it's thing and then, after f finishes, statement2 is executed.
Now, let's think about your problem. I can see that your hard work on this question from the second program you've written, but forget about it, the first one is very close to the answer.
Let's think about what your function does. It prints all numbers from n to 0 and then from 0 to n. At the first step, you want to print n, then all the numbers from n-1 to 0 and from 0 to n-1, and print another n. See where it's going?
So, you have to do something like this:
print(n)
call f(n-1)
print(n)
I hope my explanation is clear enough.
This is more of hack -- using the std::stream rather than recursion...
void rec(int n) {
if (n==1) { cout << 1; return; }
cout << n;
rec(n-1);
cout << n;
}
int main() {
rec(3);
}
prints
32123

simple recursion tracing understanding stacks

I'm working on a fairly easy tracing exercise however I'm not completely understanding why the solution is what it is...
void f( int n) {
if (n>0) {
f(n-1)
cout << n << " ";
}
}
int main () {
f(5);
return 0;
}
the answer is 1 2 3 4 5, however I'm wondering how this is so, since everytime the function f is called it never gets to the cout line...I understand that there is a stacking system where the last function implemented is looked at, however until the factorial example where it returned a value to multiply to the previous n, I'm not understanding how this is similar. Please don't use the factorial example again, I do understand it, but I'm not udnerstanding how the cout is implemented here.. thank you for your help.
Consider the simple case of calling f(1). We pass the if test and make a recursive call to f(0). This call will return doing nothing and continue executing the body of f(1). The next statement is the call to std::cout << 1 << " ";:
// Substitute the parameter with the passed in argument n = 1
void f(1) {
if (1 > 0) {
f(0);
std::cout << 1 << " ";
}
}
You should now be able to handle the case of f(2), and in general f(n). Whenever you are stuck thinking about recursive programs, consider the base cases and then generalize. Write the code out by substituting the function parameters with actual arguments.
It does get to the output line, after the recursive call to f returns.
The important part here is the stopping condition:
if (n>0)
This makes the recursive call only happen if n is larger than zero. And as the recursive call is with the argument n - 1 it will be lower and lower until it's zero and no more calls will be made.
Lets trace it for you, since you are to lazy to do it yourself in a debugger (or on paper):
The first call from main is made. n == 5 and clearly larger than zero, so a recursive call is made with 5 - 1
In the second call, n == 4, still larger than zero so a call is made again with 4 - 1
In the third call, n == 3, still larger than zero so a call is made again with 3 - 1
In the fourth call, n == 2, still larger than zero so a call is made again with 2 - 1
In the fifth call, n == 1, still larger than zero so a call is made again with 1 - 1
In the sixth call, n == 0, which is not larger than zero, so no more calls are made and the function returns.
Returns to n == 1, and so 1 is printed and then the function returns
Returns to n == 2, and so 2 is printed and then the function returns
Returns to n == 3, and so 3 is printed and then the function returns
Returns to n == 4, and so 4 is printed and then the function returns
Returns to n == 5, and so 5 is printed and then the function returns to the main function
That is, this is how it should have worked if it compiled. Now it won't even get this far since you will have compiler errors (with the code as shown in your question).

Recursion in c++ Factorial Program

hello i have this piece of code that i coded based on some other recursion and factorial programs
but my problem is that i am really confused as to how it stored the value and kept it and then returned it at the end
int factorialfinder(int x)
{
if (x == 1)
{
return 1;
}else
{
return x*factorialfinder(x-1);
}
}
int main()
{
cout << factorialfinder(5) << endl;
}
so 5 goes in, and gets multiplied by 4 by calling its function again and again and again, then it gets to one and it returns the factorial answer
why? i have no idea how it got stored, why is return 1 returning the actual answer, what is it really doing?
Source: Image is taken from: IBM Developers website
Just take a look at the picture above, you will understand it better. The number never gets stored, but gets called recursively to calculate the output.
So when you call the fact(4) the current stack is used to store every parameter as the recursive calls occur down to factorialfinder(1). So the calculation goes like this: 5*4*3*2*1.
int factorialfinder(int x)
{
if (x == 1) // HERE 5 is not equal to 1 so goes to else
{
return 1;
}else
{
return x*factorialfinder(x-1); // returns 5*4*3*2*1 when x==1 it returns 1
}
}
Hope this helps.
Return 1 is not returning the actual answer. It's just returning the answer to calling
factorialfinder(1);
which happens in your code.
In any program, a call stack is a space in memory that is used to keep track of function calls. Space from this memory is used to store the arguments to a function, as well as the return value of that function. Whenever some function A calls another function B, A gets the return value of B from that space.
A recursive function is nothing special, it's just an ordinary function calling another function (that happens to be itself). So really, when a recursive function F calls itself, it's calling another function: F calls F', which calls F'', which calls F''', etc. It's just that F, F'', F''' etc. execute the same code, just with different inputs.
The expression if (x == 1) is there to check when this process should be stopped.
The return value of F''' is used by F''. The return value of F'' is used by F'. The return value of F' is used by F.
In Factorial of some number, the operation is (n) * (n-1) * (n-2) * .... * (1).
I've highlighted the 1; this is the condition that's being checked.
A recursive function breaks a big problem down into smaller cases.
Going over your program:
call factorialfinder with 5, result is stored as 5 * factorialfinder(4)
call factorialfinder with 4, result is stored as 5 * 4 * factorialfinder(3)
call factorialfinder with 3, result is stored as 5 * 4 * 3 * factorialfinder(2)
call factorialfinder with 2, result is stored as 5 * 4 * 3 * 2 * factorialfinder(1)
call factorialfinder with 1, result is stored as 5 * 4 * 3 * 2 * 1
in essence it combines the result of a stack of calls to factorialfinder until you hit your base case, in this case x = 1.
Well, the factorial function can be written using recursion or not, but the main consideration in the recursion is that this one uses the system stack, so, each call to the function is a item in the system stack, like this (read from the bottom to the top):
Other consideration in the recursion function is that this one has two main code piece:
The base case
The recursion case
In the base case, the recursive function returns the element that bounds the algorithm, and that stop the recursion. In the factorial this element is 1, because mathematically the factorial of number one is 1 by definition. For other numbers you don't know the factorial, because of that, you have to compute by using the formula, and one implementation of it is using recursion, so the recursive case.
Example:
The factorial of 5, the procedure is: 5*4*3*2*1 = 120, note you have to multiply each number from the top value until number 1, in other words, until the base case takes place which is the case that you already knew.
#include<iostream>
using namespace std;
int factorial(int n);
int main()
{
int n;
cout << "Enter a positive integer: ";
cin >> n;
cout << "Factorial of " << n << " = " << factorial(n);
return 0;
}
int factorial(int n)
{
if(n > 1)
return n * factorial(n - 1);
else
return 1;
}