How does this function count the number of nodes in a tree? - c

A function to count the number of nodes in a tree.
int count(node *t)
{
int i;
if (t == NULL)
return(0);
i = 1 + count(t->left) + count(t->right); // recursion occurs address of left node is passed and
return(i); // continue to pass until whole left node
} // is traversed and the value of t is
// NULL and 0 is returned same for right node counting
// i = 1 + 0 + 0 = 1
How is the number of nodes counted ?

To understand recursion, you must first understand recursion.

That's a recursive implementation of counting tree nodes. It is called for the root node and returns "one plus number of nodes in left subtree plus number of nodes in the right subtree", that is done recursively until it reaches leaf nodes.

The total count includes the current/root node plus the count on the left branch plus the count on the right branch. Your sentinel is the NULL which means you've reached the leaf node of whatever branch you are currently counting. Then you unwind back up. Recursion :)

First, have you tried it yourself?
Basically, it adds 1 for every non-null node. It's roughly like this: 1 + number_of_nodes_to_the_left + number_of_nodes_to_the_right. This expands to: 1+(1+number_of_nodes_to_the_left_in_left+number_of_nodes_to_the_right_in_left) + (1+number_of_nodes_to_the_left_in_right + number_of_nodes_to_the_right_in_right). Keep on expanding and you'll see that it's basically 1 + 1 + 1 +.... for every non-null node in the tree.
EDIT: To illustrate this better, consider the following tree:
Node0
|
(left) | (right)
Node1 _|_ Node2
|
(left) | (right)
Node3 _|_ Node4
When you do int node_count = count(Node0), since Node0 is not NULL, it goes to the return statement which is:
return 1 + count(left) + count(right). You need to understand a basic thing that very operation in your recursion function happens one-after-the-other.In other words operation count(right) doesn't happen until operation count(left) is completed. Now take a look at the return statement you have there and translate it in terms of the above tree. It would be 1+count(Node1)+count(Node2). So count(Node2) doesn't get calculated before count(Node1) has finished. So for count(Node1), count function gets called (again) with Node1 as the argument. So let us, for now, forget about the semi-calculated expression 1+count(Node1)+count(Node2) (we'll come back to it later).
Now for count(Node1), Node1 is not NULL and hence proceeds to the return statement. This would (again) be 1+count(left)+count(right). But wait, Node1 doesn't have left and right nodes. So, when count(left) gets called with the argument being NULL, it returns 0 and the same happens for count(right). So the expression for count(Node1) becomes 1 + 0 + 0. There are no more count functions being called for Node1 and hence it returns to it's original caller, which was the return statement of count(Node0).
Since we have count(Node1) figured out, let's replace it in the return statement of count(Node0). This now becomes 1 + (1 + 0 + 0) + count(Node2).
Now I'm going to make this a bit faster. Since Node2 has two children, the return statement of Node2 will be 1 + count(Node3) + count(Node4). Just like it was for Node1, count(Node3) and count(Node4) will each return 1 + 0 + 0, turning the return statement of count(Node2) to be 1 + (1 + 0 + 0) + (1 + 0 + 0).
Now that count(Node2) has been fully calculated, let's return to the original caller of count(Node2), which is 1 + (1 + 0 + 0) + count(Node2). Replace what we got from count(Node2) in there and we get 1 + (1+0+0) + (1 + (1+0+0) + (1+0+0)). Add it up and we get the value of 5. This value gets returned to whichever function that called count(Node0), like the statement int node_count = count(Node0) and node_count will have the value 5.

Consider these trees:
A tree with no nodes (i.e. a NULL pointer) - returns 0
A tree with one node, the root. This will call:
i=1+count(t->left)+count(t->right);
with left and right NULL, and so will return 1 + 0 + 0
A tree with a root and a single right leaf
i=1+count(t->left)+count(t->right);
will return 1 for the root, 0 for the tree rooted at left (by the rules above) and 1 for the tree rooted at right (by the rules above), which is 1 + 0 + 1
And so on.

Related

How does this function compute the number of nodes in binary tree

I've a function that I'm trying to analyze which its output is 7:
Given this block of code:
int func_1(struct node* node)
{
if (node == NULL)
return 0;
else
return func_1(node->left) + 1 + func_1(node->right);
}
And this Binary Search Tree:
The return value is 7.
I know recursion and it's kinda simple here, I tried to follow up and I can not understand how it returned 7. I calculated that it just goes left, left, then one time right, and that's it. which will return 3. And even if it goes 3 times right, after the root, it will still return 6 and not 7.
Can you guys help me out please?
Semantically it takes the number of left nodes + 1 (the current node) + the number of right nodes.
with func_1(x) I mean calling the function on that specific node.
So the complete calculation is
func_1(8) + 1 + func_1(14)
(func_1(7) + 1 + func_1(9)) + 1 + func_1(14)
(1 + 1 + 1) + 1 + (0 + 1 + func_1(17)
3 + 1 + (0 + 1 + (0 + 1 + func_1(18))
3 + 1 + (1 + (1 + (0 + 1 + 0)
results in 7
This principle is used very often in recursion:
first do the calculation for the 'current' item (the current node), in this case the number of nodes for the 'node itself' is 1.
than add the calculation of the other items in a recursive way, in this case the number of nodes left of the current node, and the number of nodes right of the current node. For ordering reasons in this case the +1 for the current node (number of nodes) is put in the middle.
Take a look at the leaf node 7.
When func_1 is called with the value of the node 7, the if statement will branch into the else part, since the pointer to this node is valid.
Then func_1 will be called twice once for the left child and once for the right child. In both cases the functions return 0, since left and right child are NULL. The function will return 1:
return func_1(node->left) + 1 + func_1(node->right);
equivalent to:
return func_1(NULL) + 1 + func_1(NULL);
becomes:
return 0 + 1 + 0;
Look at this statement
return func_1(node->left) + 1 + func_1(node->right);
^^^^^
if a node is not equal to NULL it counts itself plus the number of nodes in the left and right sub trees relative to this node.
So you will get a result that is equal to the number of nodes that are not equal to NULL.

VBA Run-time error 13 - type mismatch- price time series calc not working on array

I suspect my question has a very simple answer, and yet I cannot find an answer that I understand in searching all over the site.
Ticker1 = an array of stock prices (1 to 2542)
PctChg1 = an array which I hope will ultimately hold the results of
(Price_last / Price_prev) - 1
i = counter
Code:
For i = 2 To UBound(Ticker1)
PctChg1(i, 1) = Ticker1(i, 1) / Ticker1(i - 1, 1) - 1
Next i
Something about the Ticker1(i - 1, 1) part it does not like - I have fooled around with ranges as well and cannot make sense of this. I don't know why it thinks I am dividing by a number that isn't there - if i am starting at point 2 of the array, why wouldn't I be able to reference point 1 ?
For i = 2 To UBound(Ticker1)
If Val(Ticker1(i - 1, 1)) <> 0 Then PctChg1(i, 1) = Ticker1(i, 1) / Ticker1(i - 1, 1) - 1
Next i
This works, but I still have not established why i-1 generates errors when I start the calculation on data point i=2.

Questions related to recursion

Please find the code below which shows some operations based on recursion.I would love some one to please explain me how this recursion works?
#include <stdio.h>
int func(int);
main()
{
int ret = 0;
ret = func(6);
printf("The val is %d\n",ret);
}
int func(int m)
{
if((m==0)||(m==1))
{
return 1;
}
else
{
return (func(m-1)+func(m-2));
}
}
When executed,the value of val is 13.Please someone explain how does this unwind operations happens in stack
You don't need to involve a stack or any unwinding (excuse me for involving myself, though).
Just substitute the call with the content of the function, and keep doing that until you no longer recurse:
ret = func(6) =
func(5) + func(4) =
func(4) + func(3) + func(3) + func(2) =
func(2) + func(3) + func(1) + func(2) + func(1) + func(2) + func(0) + func(1) =
func(0) + func(1) + func(1) + func(2) + 1 + func(0) + func(1) + 1 + func(1) + func(0) + 1 + 1 =
1 + 1 + 1 + func(0) + func(1) + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 =
3 + 1 + 1 + 8 =
3 + 2 + 8 =
13
It's a bit difficult with the typography, but that's what happens and the answer seems to match what you got, too.
Recursion is nothing more than calling the a function from within that particular function. A lot of mathematical algorithms or (tree) search algorithms use this technique for their desired result.
Recursive function calls need to 'escape' their repeating 'self calling' otherwise the application would become unresponsive. In your example, this is done by the if((m==0)||(m==1)) check. If the check is true, the function just returns 1 (and escapes the recursion).
The recursive code you showed calculates the Fibonacci sequence, which is a typical recursive algorithm, as it requires the values of 2 previous calculations. Step 0 and 1 return 1. These 2 values are added for step 2 (resulting in 1+1=2). The next step results in 1+2=3. And so on. As you see this can only be calculated from the start (and thus requires the recursion to do so)
Your program tries to print the nth(or n+1th) number of a Fibonacci series. Here the base case is when m =1 or m=0
The worst thing about recursion here is a value is calculated twice for example func(4), func(3) and func(2) as evident from here.

What will be the DFA for the regular expression 0(0+1)*0+1(0+1)*1?

This is the DFA i have drawn-
Is it correct?
I am confused because q4 state has 2 different transitions for same input symbol which violates the rule of DFA, but I can't think of any other solution.
Your DFA is not correct.
your DFA is completely wrong so I don't comment
DFA for RE:
0(1 + 0)*0 + 1(1 + 0)*1
Language Description: if string start with 0 it should end with 0 or if string start with 1 it should end with 1. hence two final states (state-5, state-4).
state-4 : accepts 1(1 + 0)*1
state-5 : accepts 0(1 + 0)*0
state-1 : start state.
DFA:
EDIT :
+ Operator in Regular Expression
(0 + 1)* = (1 + 0)* that is any string consist of 1s and 0s, including Null string ^.
Here + means Union if it appear between two RE: and A U B = B U A (similarly)=> (0 + 1) = (0 + 1) .
meaning of plus + depends on syntax it appears in: If expression is a+ (+ is superscripted) this means one of more as, and If a+b then + means Union operation either a or b.
a+ : { a, aa, aaa, aaa.....} that is any number of a string in language with length > 1.
I think you should start with 0 first
0(1 + 0)*0 + 1(1 + 0)*1

Traversing a scheme-like tree (graph) dump using C

I have a Scheme-like tree graph structure. I want to parse it using C into some in-memory representation and walk over it.
It there any library or front-end of parser to do this?
EDIT:
I have parsed the following expression
true && (false || true) ;
true ;
false || false
into following (This is my scheme-like tree dump)
(PROG [(AndExp TVal(OrExp FValTVal)), TVal, (OrExp FValFVal)])
Which I want to traverse using C ( I have to give it to someone else who only works with C). PROG is a label; AndExp, OrExp etc are tokens for &&, || etc ..
It seems like this is a form of S-Expression. Perhaps This S-Expression Parser can be modified for your needs.
I think i have understood your requirement, but not quite sure.
You have the expressions in prefix notation, therefore this is basically loading the prefix expression you have in your dump file in binary tree.
Here is a pseudocode which described the process to load the expressions into a tree.
tree_node make_tree (string dump)
{
tok1 = get_tok (dump);
tok2 = get_tok (dump);
tok3 = get_tok (dump);
if (tok1 == operand)
{
node = make_new_node_with (tok1);
return node;
}
node = make_new_node_with (tok1);
node->left = make_tree (tok2);
node->right = make_tree (tok3);
return node;
}
Recursive call 1 with (AndExp TVal(OrExp FValTVal))
tok1 = AndExp makes a new node1
tok2 = TVal
tok3 = (OrExp FValTVal)
Recursive call 2 with TVal returns node2 to call 1 which links it with the left pointer of node1.
Recursive call 3 with (OrExp FValTVal) from call 1.
tok1 = ORExp makes a new node3
tok2 = FVal
tok3 = TVal
Recursive call 3 with FVal and call 4 with TVal respectively returns node4 and node5 with the operand values, which are linked to the left and right links of the node3 from call 3.
No more subexpression to be considered, recursion returns back to starting point. You have the root of the tree.
( node1 )
|AndExp |
+---+---+
|
+------------+------------+
| |
( node2 ) ( node3 )
| TVal | | ORExp |
+---+---+ +---+---+
|
+-----------+-----------+
| |
( node4 ) ( node5 )
| FVal | | TVal |
+---+---+ +---+---+
If there are more than two operands , processing can be done similarly by adding additional links to the tree nodes.
For each expression in your dump file, which are separated by commas will have separate trees, which after creation can be traversed.

Resources