【发布时间】:2020-03-23 07:58:40
【问题描述】:
我很难理解为什么下面的函数CountNodes() 会计算 BST 中的所有节点。
如果我们假设我们有以下 BST:
20
/ \
10 30
/ \ / \
5 15 25 35
如果我打电话给CountNodes(pointer to root node 20); 那么相关的if 声明不会:
if(root->left!=NULL)
{
n=n+1;
n=CountNodes(root->left);
}
只需查看节点 10 并说,是的,它不为空,将 1 加到计数器 n,然后调用 CountNodes(pointer to 10),这将再次将我们从左分支发送到 5。那么当5left和right变量是NULL,因此整个CountNodes函数只返回n等于int 3。
我想我很难准确理解 CountNodes 的参数值何时更新。我们是否查看right 并检查其NULL 是否并更新计数器,然后在左侧查看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;
}
【问题讨论】:
-
我会避免使用全局变量
n。在递归中使用具有副作用的全局变量是非常错误的...... -
我建议您尝试找到一个解决方案,其中
n是一个本地变量而不是全局变量。 -
首先,您绝对应该将n定义为
countNodes的局部变量。然后通过 分配 n 作为递归调用的结果,您会丢失以前的信息。你需要+=而不是...... -
另外,通过
n = ...后跟n = ...你会丢失第一个作业。 -
实际上,您可以非常简单地做到这一点:
return root == nullptr ? 0 : 1 + count(root->left) + count(root->right);– 下一个递归调用中的 null-check 补偿了对可用子项的丢弃检查。1 + ...计算当前节点本身,它取代了您现在拥有的n = n + 1。
标签: c++ recursion binary-search-tree