Confused in understanding recursion - c

I am little bit confused with the following code to find height of the tree and the code to find sum of n nos recursively, which is below this. What does the lheight and rheight store, depending on the number of recursions it makes?
int height(struct node* node)
{
if (node==NULL)
return 0;
else
{
lheight = height(node->left);
rheight = height(node->right);
if (lheight > rheight)
return(lheight+1);
else return(rheight+1);
}
}
Here is one more clarification, it prints the sum of n nos:
int findSum(int n){
int sum;
if(n <= 0) return 0;
else sum = n + findSum(n-1);
return sum;
}
if I change this to:
int findSum(int n){
int sum;
if(n <= 0) return 0;
else sum = findSum(n-1); // here
return sum;
}
It prints the output as 0. Why doesn't this return the number of recursions, if the above tree code does?

Your second recursion is equivalent to
sum = findSum(n-1) = findSum(n-2) = findSum(n-3) = ..... = findSum(0) = 0;
If you want that the second recursion return the number of recursion then use
sum = 1 + findSum(n-1);
the lheight and rheight return the tree level because in the recursion function there is incrementation with 1 for both variables:
return(lheight+1);
else return(rheight+1);
If you want your findsum() do the samething as your height() recusrsion you should return sum+1 and not sum at the end of your findsum() function:
int findSum(int n){
int sum;
if(n <= 0) return 0;
else sum = findSum(n-1);
return sum+1; //<<<<< should return sum +1 as you did in the height function
}
the return sum+1; will be evaluated only if the
findSum(n-1); findSum(n-2); findSum(n-3); ...findSum(0); are called.
when findSum(0) is called, it will return 0;
when findSum(1) is called, it will execute sum=findSum(0) (so sum
= 0) and then return sum+1 (1);
when findSum(2) is called, it will execute sum=findSum(1) (so sum
= 1) and then return sum+1 (2);
when findSum(3) is called, it will execute sum=findSum(2) (so sum
= 2) and then return sum+1 (3);
.
.
.
when findSum(n) is called, it will execute sum=findSum(n-1) (so
sum = n-1) and then return sum+1 (n);

I suggest you do this on paper. If we do it for the (unmodified) findSum function it will be like this:
Lest say you call it like
findSum(2);
This will read to the following steps:
1: sum = 2 + findSum(2 - 1);
Which will call findSum(1) which leads to
2: sum = 1 + findSum(1 - 1);
which calls findSum(0) which is
3: return 0;
Now we go back up one step to 2:
2: sum = 1 + 0;
and back up once more:
1: sum = 2 + 1
So the result of findSum(2) is 3.

lheight and rheight are nothing but the heights of left subtree and right sub tree resp at a particular level of the Tree.
This can be made easier to understand if you take up an example.
In the attached figure, we start off with root F. We check if the root is null, or not, and since it is not , we find the height of right subtree and left subtree, and whichever is more, we add one more to it and return. This is how we would do it manually.
Now while finding the height of left sub tree, we recursively go down, till we reach a null pointer, at which point we return 0. Hence the value return for A is 0, and then we check the height of right sub tree (i.e D) and for that we recursively go down till C, for which 0 is returned, and similarly 0 is returned for 0. We add one to the max of C and E (i.e 0) and return it to the upper level. Now we have value 0 for A and 1 for D, we add one to the max ( i.e. 1) and return it to the upper level. Which is the height of left subtree of the complete tree, similarly the height of right subtree is calculated.

Related

recursive Function, to find even or odd digits inside given number

Basically, its printing only one instance when it happens, and i don't understand why, maybe has something to do with the code reseting every time and starting the variable at 0 again, and i got another question if someone can help me with, i have to return both values when its odd and even, like how many digits are even and odd at the same time, i'm having a little trouble figuring out how to do it
#include <stdio.h>
int digits(int n)
// function that checks if the given value is odd or even, and then add
// + 1 if it's even, or odd, it's supposed to return the value of the quantity
// of digits of the number given by the main function
{
int r;
int odd = 0;
int even = 0;
r = n % 10;
if (r % 2 == 0) // check if given number is even
{
even = even + 1;
}
if (r % 2 != 0) // check if its odd
{
odd = odd + 1;
}
if (n != 0) {
digits(n / 10); // supposed to reset function if n!=0 dividing
// it by 10
}
if (n == 0) { return odd; }
}
int
main() // main function that sends a number to the recursive function
{
int n;
printf("type number in:\n ");
scanf("%d", &n);
printf("%d\n", digits(n));
}
odd and even variables are local in your code, so they are initialized by zero every time.
I think they should be declared at caller of the recursive function, or be declared as global variables.
#include <stdio.h>
void digits(int n, int *even, int *odd)//function
{
int r;
r = n % 10;
if (r % 2 == 0)//check if given number is even
{
*even = *even + 1;
}
else //otherwise, its odd
{
*odd = *odd + 1;
}
n /= 10;
if (n != 0)
{
digits(n, even, odd);//supposed to reset function if n!=0 dividing it by 10
}
}
int main()
{
int n, even = 0, odd = 0;
printf("type number in:\n ");
scanf("%d", &n);
digits(n, &even, &odd);
printf("even: %d\n", even);
printf("odd: %d\n", odd);
return 0;
}
Maybe I found the problem you are facing. You you initialized you odd and even variable as zero. every time you call the function it redeclares their value to zero again. You can use pointer caller or use those as your global variable so that every time they don't repeat their initial values again.
Implementing a function that counts the number of odd and even digits in a number, is not to be done using recursive. That is simply a wrong design choice.
But I assume that it's part of your assignment to use recursion so ... okay.
You want a function that can return two values. Well, in C you can't!! C only allows one return value. So you need another approach. The typical solution is to pass pointers to variables where the result is to be stored.
Here is the code:
void count_odd_even(const int n, int *even, int *odd)
{
if (n == 0) return;
if (((n % 10) % 2) == 1)
{
*odd += 1;
}
else
{
*even += 1;
}
count_odd_even(n/10, even, odd);
}
And call it like
int odd = 0;
int even = 0;
count_odd_even(1234567, &even, &odd);

Finding proper divisors in c

I'm trying to write a function that finds the number of divisors of a number n, which are smaller or equal to a number k using recursion (in C programming language).
For example, (9,3) should return 2 since the only positive divisors of 9 that are less than or equal to 3 are 1 and 3.
Here's what I've tried but can't figure out why it's not working:
int divisors(int n,int k){
int sum = 0;
if (k==0){
return 0;
}
else if (n%k==0){
return sum++ + divisors(n,k-1);
}
return sum;
}
If anyone is able to help I'd appreciate it.
You are almost there. I made a few fixes:
k == 1 as a break condition is faster, although k == 0 works fine.
The integer sum is useless.
When not counting, your thinking was almost correct. You should return 0 but for this specific case while keeping the function calculating the next ints (recursion). Therefore you should return 0 + divisors(n, k-1)
int divisors(int n,int k){
if (k == 1) return 1;
if (n % k == 0) return 1 + divisors(n, k-1);
return divisors(n, k-1);
}
You are not handling the resolution of the recursion properly
There is no need for a sum variable, instead you want to return the function call (or 0) in any case.
If you find a number so that n%k==0 holds true, you want to return 1 + the results of the next case. However, if you then find a number that is neither 0, nor a match it will stop, instead of checking all numbers down to 0. Therefore adjusting your code in the following way will solve the problem:
int divisors(int n,int k){
if (k==0)
return 0;
else if (n%k==0)
return divisors(n,k-1) + 1;
else
return divisors(n,k-1);
}

why is my variable storing value from previous recursion runs?

the first image is of the Program with regular recursion format, I am returning values for both cases but self call to the function is made only when the argument is a natural number. The result is as expected
in the second program, however, I am not returning any value for natural numbers, the only return case is when the argument is 0.
Ideally, (taking 5 as the input) recursion will happen till num value equals 0. First with
sum = 5 + add(5-1);
sum = 4 + add(4-1);
sum = 3 + add(3-1);
sum = 2 + add(2-1);
sum = 1 + add(1-1);
At this stage, the function will return 0 as flow moves to else block,and value of sum for that loop is 0.
Now, with 0 being returned we rise one step up and 0 will take place of add(1-1) in the line
sum = num + add(num-1);
it should look like
sum = 1 + 0;
the function add(num) should terminate now, after assigning 1 to variable sum.
Two main questions.
No value should rise up for sum = 2 + add(2-1), as in the previous step no value is returned. for add(1), after getting value from add(0), summation of 1 and returned value is stored in variable sum and then exits out of function body.
Every time recursion occurs new variable sum is declared and initiated to 0, so, I don't see why the computer is storing the values of the sum from previous calls to the function, when instead it should start a fresh new variable sum.
to me, after completion of code, the value of variable sum in add() should be 1.
Please someone, if you can make sense of this code. Let me know. Much appreciated
P.s: you can try this on any online C compiler as well. Here is the code:
#include <stdlib.h>
#include <stdio.h>
int add(int num);
int main(){
int number,sum;
printf("enter a number of your choice: ");
scanf("%d",&number);
sum = add(number);
printf("SUM = %d",sum);
}
int add(int num){
int sum = 0;
if(num != 0)
sum = num + add(num-1);
else
return sum;
}
sum = add(number);
Using the return value of a function that flowed off the end without explicitly returning a value is undefined behavior. UB means anything is allowed to happen, including giving you the (false) illusion that a variable is "storing value from previous recursion runs". Quoting from C11 6.9.1/12:
If the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined.
A function declared to return an int must always return a value (i.e. an int value). Your code doesn't.
int add(int num){
int sum = 0;
if(num != 0)
// If the execution gets in here
sum = num + add(num-1);
else
return sum;
// it will continue here (when the recursion ends).
// And here it is WITHOUT a returned value - that's bad.
}
You probably want:
int add(int num){
int sum = 0;
if(num != 0)
sum = num + add(num-1);
return sum;
}
or
int add(int num){
if(num != 0)
return num + add(num-1);
else
return sum;
}
or (more clear and secure):
int add(int num){
if(num <= 0)
{
return 0;
}
return num + add(num-1);
}

quicksort comparison count intermittent results

SOLUTION the solution is unique to my code -- I placed srand(time(NULL)); inside the loop when it should've been placed outside
I'm trying to count the number of comparisons in a quick sort algorithm. I had a recursive version working fine, but it kept seg faulting because I was using large array sizes -- running out of stack space.
So now I've resulted to an iterative approach, and it works. That is, except for my counter for the number of comparisons.
It's returning intermittent results such as...
unsorted: [9][8][7][6][5][4][3][2][1][0]
sorted: [0][1][2][3][4][5][6][7][8][9]
Numer of comparisons: 22
unsorted: [9][8][7][6][5][4][3][2][1][0]
sorted: [0][1][2][3][4][5][6][7][8][9]
Numer of comparisons: 19749794
unsorted: [9][8][7][6][5][4][3][2][1][0]
sorted: [0][1][2][3][4][5][6][7][8][9]
Numer of comparisons: 6088231
my code for the iterative quick sort is...
#include <time.h>
#define BUFLEN 6400
extern int buf[BUFLEN];
extern int quick_count; //comparison count
struct stack {
int stk[BUFLEN];
int top;
};
struct stack s;
void push(int x);
int pop();
void iterative_quick_sort (int buf[], int n) {
int left_ptr, right_ptr, pivot_index, pivot, temp, l, r;
if (n < 2) //case the partitioning has reached the atomic element
return;
r = n - 1;
l = 0;
s.top = -1;
loop: do{
srand(time(NULL));
if ((r - l) == 0)
pivot_index = 1;
else {
pivot_index = rand() % (r - l);
pivot_index += l;
}
pivot = buf[pivot_index]; //pivot holds the value of the pivot element
left_ptr = l;
right_ptr = r;
if ((r - l) != 0 || (r - l) != 1){
while (1) {
while (buf[left_ptr] < pivot){ //loop and increment left_ptr until an element on the left side is larger than the pivot
left_ptr++;
} //now left_ptr holds the index of the value that needs to be swapped with an element from the right side
while (pivot < buf[right_ptr]){ //loop and increment right_ptr until an element on the right side is smaller than the pivot
right_ptr--;
} //now right_ptr holds the index of the value that needs to be swapped with an element from the left side
quick_count++;
if (left_ptr >= right_ptr)
break; //once the pivots reach or overlap each other, break the loop
//perform swap with temporary variable temp
temp = buf[left_ptr];
buf[left_ptr] = buf[right_ptr];
buf[right_ptr] = temp;
}
}
if (l == (n - 2))
break;
else if ((r - l) >= 2){
//goto loop with left side values
push(r);
r = pivot_index + 1;
goto loop;
}
else {
//goto loop with right side values
l = r;
r = pop();
goto loop;
}
}while(1);
}
//cite http://www.sanfoundry.com/c-program-stack-implementation/
void push (int x){
s.top = s.top + 1;
s.stk[s.top] = x;
}
int pop(){
int x = s.stk[s.top];
s.top = s.top - 1;
return x;
}
per request, I've added the function that calls quick sort (Note: quick_count is initialized to zero as a global variable -- used as an extern)
int unsorted_quick[] = {9,8,7,6,5,4,3,2,1,0}; //n = 10
//print unsorted_quick
printf("\nSecond, we sort the following array by using the quick sort algorithm\n");
for (i = 0; i < 10; i++){
printf("[%d]", unsorted_quick[i]);
}
printf("\n");
//fill buf with the unsorted quick array
for (i = 0; i < 10; i++){
buf[i] = unsorted_quick[i];
}
iterative_quick_sort(buf, 10); //call quick_sort()
//print sorted
for (i = 0; i < 10; i++){
printf("[%d]", buf[i]);
}
printf("\nNumber of comparisons: %d\n", quick_count); //print count
You are calling srand(time(NULL)) inside the loop that choose the random pivot. This function must be called once to initialise the state of the random number generator.
The generator needs a starting seed which is set by calling srand(). Then, given the seed, each subsequent call to rand() will give you a random number in a reproducible sequence.
Starting from the same seed you will get the same random sequence.
The problem is that you set the seed in the loop and the seed is the same number so you will always get the same "random" value. This happens because time(NULL) is taken from current time in seconds which means that the random number it's the same in the same second.
You must put it before the loop: do {
Here there is a nice explanation of what is happening: Problems when calling srand(time(NULL)) inside rollDice function
And also here: srand() — why call it only once?

Why does recursive function count downwards after peak?

with fear that I may overstep another question of mine (although this is a new problem alltogether) I still ask this question.
I have this code:
int blob_count(int y, int x, int gridCopy[][5], int sum){
//Local vars
int posX, posY;
//Find the position 1 behind and 1 above the starting point, and start the loop there
for(posX = -1;posX <=1; posX++){
for(posY = -1; posY <= 1; posY++){
if((y + posY) >= 0 && (x + posX) >= 0){
if((y + posY) <= 5 && (x + posX) <= 5){
if(gridCopy[posY+y][posX+x] == 1){
//Set the starting point to 0 (so it wont get calculated again)
gridCopy[posY+y][posX+x] = 0;
y = posY+y;
x = posX+x;
sum++;
blob_count(y, x, gridCopy, sum);
}
}
}
}
}
return sum;
}
The issue is that sum, which counts up 1, for each recursive run, returns the wrong value. By doing a print for each recursive run it gives the result:
sum = 1
sum = 2
sum = ...
sum = n
Which is great, however, by setting printing out the sum outside the for loop (right before return sum;) the opposite happens when it has peaked, so it does this:
sum = n
sum = ...
sum = 2
sum = 1
return sum; // = 1
Which is obviously wrong, as I want the total count, not the lowest. Have I got the return value the wrong place? I've tried putting it in right after the recursive call (inside the loop), to no avail.
Okay let's get rid of the extra bits and simplify your problem down to the essentials.
You have:
int blob_count(int sum)
{
sum++;
if (sum < 10)
blob_count(sum);
return sum;
}
If you add printf("sum==%d\n", sum) right before the return then it will be called first at the innermost recursion (where sum == 10), then it will return to the next level out where sum == 9, print that, return to sum == 8 and so on.
If you put it before the recursive call to blob_count(sum) then you'll print the values before you recurse down, so they start with sum==0, sum == 1 and so on.
If you want sumto be the deepest level your recursion got to, then you could either pass it back via the return value like this:
int blob_count(int sum)
{
sum++;
if (sum < 10)
sum = blob_count(sum);
return sum;
}
or you could pass it via a pointer so that the original variable gets modified:
void blob_count(int* sum)
{
*sum++;
if (*sum < 10)
blob_count(sum);
return;
}
The first one is probably the solution you are looking for.
What pmg said. For each recursive call, the current value of sum is copied and the copy is passed to the recursive call. If you want to modify objects in functions, you must pass a pointer to these objects instead of the object itself.

Resources