这个函数如何计算树中的节点数?
计算树中节点数量的函数。
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
节点数是如何计算的?
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 ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
要了解递归,你必须首先了解递归。
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.
总计数包括当前/根节点加上左分支的计数加上右分支的计数。您的哨兵是 NULL,这意味着您已到达当前正在计数的任何分支的叶节点。然后你就放松下来。递归 :)
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 :)
首先,你自己尝试过吗?
基本上,它为每个非空节点加 1。大致如下:
1 + number_of_nodes_to_the_left + number_of_nodes_to_the_right
。其扩展为: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)
。继续扩展,您会发现树中的每个非空节点基本上都是1 + 1 + 1 +....
。编辑:为了更好地说明这一点,请考虑以下树:
当您执行
int node_count = count(Node0)
时,由于 Node0 不为 NULL,因此它会转到 return 语句,其中是:返回 1 + 计数(左)+ 计数(右)
。您需要了解一件基本的事情,即递归函数中的每个操作都是相继发生的。换句话说,直到操作count(left) 之前,操作
已完成。现在看一下那里的 return 语句,并根据上面的树进行翻译。它将是count(right)
才会发生)1+count(Node1)+count(Node2)
。因此,在count(Node1)
完成之前不会计算count(Node2)
。因此,对于count(Node1)
,将再次以 Node1 作为参数调用 count 函数。现在,让我们暂时忘记半计算表达式1+count(Node1)+count(Node2)
(我们稍后会再讨论它)。现在,对于
count(Node1)
,Node1 不为 NULL,因此继续执行 return 语句。这将(再次)是1+count(left)+count(right)
。但是等等,Node1 没有左节点和右节点。因此,当以 NULL 参数调用count(left)
时,它会返回 0,count(right)
也会发生同样的情况。因此,count(Node1)
的表达式变为1 + 0 + 0
。不再为 Node1 调用计数函数,因此它返回到其原始调用者,即count(Node0)
的返回语句。既然我们已经计算出了
count(Node1)
,那么让我们将其替换为count(Node0)
的 return 语句。现在变为1 + (1 + 0 + 0) + count(Node2)
。现在我要让它更快一点。由于 Node2 有两个子节点,因此 Node2 的返回语句将为
1 + count(Node3) + count(Node4)
。就像 Node1 一样,count(Node3)
和count(Node4)
将分别返回1 + 0 + 0
,从而改变 return 语句count(Node2)
为1 + (1 + 0 + 0) + (1 + 0 + 0)
。现在
count(Node2)
已完全计算完毕,让我们返回到count(Node2)
的原始调用者,即1 + (1 + 0 + 0) + 计数(节点2)。替换我们从
count(Node2)
得到的内容,我们得到1 + (1+0+0) + (1 + (1+0+0) + (1+0+ 0))
。将其相加,我们得到5
的值。 此值将返回给调用count(Node0)
的函数,例如语句int node_count = count(Node0)
和node_count
的值为5
。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 basically1 + 1 + 1 +....
for every non-null node in the tree.EDIT: To illustrate this better, consider the following tree:
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 operationcount(right)
doesn't happen until operationcount(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 be1+count(Node1)+count(Node2)
. Socount(Node2)
doesn't get calculated beforecount(Node1)
has finished. So forcount(Node1)
, count function gets called (again) with Node1 as the argument. So let us, for now, forget about the semi-calculated expression1+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) be1+count(left)+count(right)
. But wait, Node1 doesn't have left and right nodes. So, whencount(left)
gets called with the argument being NULL, it returns 0 and the same happens forcount(right)
. So the expression forcount(Node1)
becomes1 + 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 ofcount(Node0)
.Since we have
count(Node1)
figured out, let's replace it in the return statement ofcount(Node0)
. This now becomes1 + (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)
andcount(Node4)
will each return1 + 0 + 0
, turning the return statement ofcount(Node2)
to be1 + (1 + 0 + 0) + (1 + 0 + 0)
.Now that
count(Node2)
has been fully calculated, let's return to the original caller ofcount(Node2)
, which is1 + (1 + 0 + 0) + count(Node2)
. Replace what we got fromcount(Node2)
in there and we get1 + (1+0+0) + (1 + (1+0+0) + (1+0+0))
. Add it up and we get the value of5
. This value gets returned to whichever function that calledcount(Node0)
, like the statementint node_count = count(Node0)
andnode_count
will have the value5
.考虑这些树:
一棵没有节点的树(即 NULL 指针) - 返回 0
一棵只有一个节点(即根)的树。这将调用:
with left 和 right NULL,因此将返回 1 + 0 + 0
具有根和单个右叶的树
将返回 1 表示根,0 表示以左侧为根的树(根据上述规则),并且1 表示以右侧为根的树(根据上述规则),即 1 + 0 + 1
等等。
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:
with left and right NULL, and so will return 1 + 0 + 0
A tree with a root and a single right leaf
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.