简体   繁体   English

计算二叉搜索树 C++ 中的节点数

[英]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.我正在努力理解为什么下面的函数CountNodes()计算 BST 中的所有节点。

If we assume we have the following BST:如果我们假设我们有以下 BST:

            20
          /   \
         10    30
        /  \  /  \
       5  15 25  35

If I call CountNodes(pointer to root node 20);如果我调用CountNodes(pointer to root node 20); then wouldn't the relevant if statement:那么相关的if语句就不会:

    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 .只需查看节点10并说,是的,它不为空,将 1 添加到计数器n ,然后调用CountNodes(pointer to 10) ,然后将我们再次发送到左分支到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 .然后,当在5leftright的变量是NULL ,因此整个CountNodes函数只是返回n等于int 3

I guess I am struggling to understand exactly when the value of the argument to CountNodes is updated.我想我很难准确理解CountNodes的参数值CountNodes更新。 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?我们是否right看并检查它是否为NULL并在我们更新左CountNodes(pointer to 10)CountNodes(pointer to 10)的第一次递归调用中的参数值之前更新计数器,即使右看出现在代码中的左递归调用之后?

#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;
}

You are overwritting the value of n您正在覆盖 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.所以你不需要在进行递归调用之前测试 null。

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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM