Reno
Reno

Reputation: 1139

Counting number of nodes in Binary Search Tree C++

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

Answers (1)

Loki Astari
Loki Astari

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

Related Questions