Reputation: 1139
I am struggling to understand why the function CountNodes()
below counts all the nodes in a BST.
If we assume we have the following BST:
20
/ \
10 30
/ \ / \
5 15 25 35
If I call CountNodes(pointer to root node 20);
then wouldn't the relevant if
statement:
if(root->left!=NULL)
{
n=n+1;
n=CountNodes(root->left);
}
simply look at node 10
and say, yes it is not null, add 1 to the counter n
, and then call CountNodes(pointer to 10)
which would then just send us down the left branch again to 5
. Then when at 5
the left
and right
variables are NULL
and hence the whole CountNodes
function just returns n
equal to int 3
.
I guess I am struggling to understand exactly when the value of the argument to CountNodes
is updated. Do we look right
and check if its NULL
and update the counter before we update the argument value in the first recursive call to CountNodes(pointer to 10)
in the left look even though the right look appears after the left recursive call in the code?
#include<iostream>
using namespace std;
int n=1;
struct node
{
int data;
node* left;
node* right;
};
struct node* getNode(int data)
{
node* newNode=new node();
newNode->data=data;
newNode->left=NULL;
newNode->right=NULL;
return newNode;
}
struct node* Insert(struct node* root, int data)
{
if (root == NULL)
return getNode(data);
if (data < root->data)
root->left = Insert(root->left, data);
else if (data > root->data)
root->right = Insert(root->right, data);
return root;
}
int CountNodes(node*root)
{
if(root==NULL)
return 0;
if(root->left!=NULL)
{
n=n+1;
n=CountNodes(root->left);
}
if(root->right!=NULL)
{
n=n+1;
n=CountNodes(root->right);
}
return n;
}
int main()
{
node* root=NULL;
root=Insert(root,10);
Insert(root,5);
Insert(root,20);
Insert(root,4);
Insert(root,8);
Insert(root,15);
Insert(root,25);
cout<<"Total No. of Nodes in the BST = "<<CountNodes(root)<<endl;
return 0;
}
Upvotes: 1
Views: 4356
Reputation: 264381
You are overwritting the value of n
n=CountNodes(root->left);
You should be adding the count from the sub tree.
n = n + CountNodes(root->left);
There is also another bug in that you are counting this node twice if the node has a left and right tree and never counting it if the node has no subtrees.
if(root->left!=NULL)
{
n=n+1; // Adding one for this node.
n=CountNodes(root->left);
}
if(root->right!=NULL)
{
n=n+1; // Adding one for this node again?
n=CountNodes(root->right);
}
I think you should be doing:
if(root->left!=NULL)
{
n = n + CountNodes(root->left);
}
if(root->right!=NULL)
{
n = n + CountNodes(root->right);
}
n = n + 1;
The next thing is that you check for null on entry into the function. So you don't need to test for null before doing a recursive call.
n = n + CountNodes(root->left);
n = n + CountNodes(root->right);
n = n + 1;
We can then simplify this to:
int CountNodes(node* root)
{
if (root == nullptr) {
return 0;
}
return 1 + CountNodes(root->left) + CountNodes(root->right);
}
Upvotes: 4