【问题标题】:recursive function calling in c++c++中的递归函数调用
【发布时间】:2022-01-24 05:28:30
【问题描述】:

有什么区别

return(checkBst(root->left, minvalue, root) && checkBst(root->right, root, maxvalue));

return(checkBst(root->left, minvalue, root));
return(checkBst(root->right, root, maxvalue));

我的整个程序是这样的

bool checkBst(node *root, node * minvalue, node * maxvalue){
    if(root == NULL){
        return true;
    }
    if((minvalue && root->data <= minvalue->data) || (maxvalue && root->data >= maxvalue->data)){
        return false;
    }
    return(checkBst(root->left, minvalue, root) && checkBst(root->right, root, maxvalue));
    // return(checkBst(root->left, minvalue, root));
    // return(checkBst(root->right, root, maxvalue));
}

【问题讨论】:

  • 主要是优化,如果 checkBst(root->left) 已经评估为 false,第一个解决方案将不会调用 checkBst(root->right)。编译器可以这样做,因为无论如何表达式都会计算为假。 (OR 类似,如果左侧已经为真,则不计算右侧)

标签: c++ recursion binary-search-tree


【解决方案1】:

坦率地说,你不能对每个函数调用都有一个返回值。这是因为 return 是在将控制权交还给调用函数之前函数中执行的最后一条语句。

在您的情况下,第二个函数永远不会被调用。所以,如果你的第一个函数返回 true,它永远不会调用第二个函数。如果第二个函数结果为假,你得到的答案将是错误的。

您仍然需要在两个语句的末尾都有一个 return 语句并捕获函数返回的值。

我的意思是这样的声明:

return(checkBst(root->left, minvalue, root) && checkBst(root->right, root, maxvalue));

等于:

ret1 = checkBst(root->left, minvalue, root);
if(ret1)
        return checkBst(root->right, root, maxvalue);
else
    return false;

递归并不是要把所有东西都放在一行中。那只是一种编码风格。 Pepijn Kramer 和一些程序员老兄的评论讨论了在同一行中编写可以得到的优化。如果前半部分为假,则无需评估后半部分,这样可以节省计算时间和精力。

递归是通过调用自身内部的相同函数并使用它的结果给出最终结果来执行重复性任务。

在您的情况下,最初您发送整棵树。然后通过调用每个子树的函数将问题分成两半。

在每个函数调用中,您都要处理终端条件。那就是您拥有的第一行和第二行。这些是您不调用更多函数的唯一情况。你得到一个返回值。

现在,这个返回值应该被传回调用函数

【讨论】:

  • 这个陈述......等于...... - 这不是真的,因为短课程。
  • 我想我是想按逻辑添加但错过了。后面我也提到了优化
  • 不,即使从逻辑上讲,它也非常不同。考虑:bool foo(int* i) { return i != nullptr &amp;&amp; *i &gt; 0; }。你会把这里的短期课程称为“优化”吗?这段代码的正确性是基于简短的课程。
  • 在这种情况下,短路只是一种优化。我并不是说短路总是与优化有关。这不是一个不同的逻辑。我更改了答案以包括短路,但我仍然说逻辑是相同的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-28
  • 1970-01-01
  • 2012-08-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多