递归函数的奇怪行为

时间:2013-12-24 17:32:51

标签: c recursion

此函数必须计算二叉树中的节点数。树包含超过1000个节点,并且递归调用的数量应该相同,但变量'count'的值不大于10.为什么?我做错了什么?

int tree_depth(BST_T *tree) {
    static int count;
    count++;
    if(tree->left!=NULL) tree_depth(tree->left);
    else if(tree->right!=NULL) tree_depth(tree->right);
    return count;
}

3 个答案:

答案 0 :(得分:2)

总结评论,您的主要问题是else。摆脱它将允许代码计算每个子树的两个分支。

另一个问题是,对于像这样的事情使用静态变量通常被认为是不好的做法。为什么不让每个调用返回它传递的子树中的节点数?这样你的代码就是线程安全的,更正确,而且更简单:

int tree_depth(const BST_T *tree)
{
    int  count = 1;

    if (tree == NULL)
        return 0;
    if (tree->left != NULL)
        count += tree_depth(tree->left);
    if (tree->right != NULL)
        count += tree_depth(tree->right);
    return count;
}

我还在树上添加了const,因为你没有以任何方式修改树,只读它。

还要注意,病理树(即一个具有所有空左链接或所有空右链接,实际上只是一个链表而不是树树)将导致 N 嵌套要求树具有 N 个节点。

<强>附录

根据下面的一些评论对上面的代码进行了一些更正。我还添加了一个额外的检查来测试树指针本身是否为空。

另外,正如@twalberg所指出的那样,使用静态计数器将在第一次调用之后的所有调用中失败,因为它在每次调用时都不会重新初始化为零。完全摆脱它会使整个事情变得更简单,并且线程安全。

答案 1 :(得分:0)

这是一种略有不同的方法:

int tree_depth(const BST_T *tree)
{ if (!tree)
    return 1 + tree_depth(tree -> left) + tree_depth(tree -> left);
  return 0;
}

除此之外,请注意tree_depth可能是此函数的一个令人困惑的名称,因为它更像count_nodes ...

答案 2 :(得分:-1)

我认为您应该对返回值执行某些操作,否则您只会收到第一级的计数。试试这个:

if(tree->left!=NULL) 
  count += tree_depth(tree->left);
else if(tree->right!=NULL) 
  count += tree_depth(tree->right);