【问题标题】:return statements in recursive calls递归调用中的 return 语句
【发布时间】:2020-01-04 20:06:26
【问题描述】:

根据我对递归调用的理解,当你通过调用函数进行递归时,该语句需要是一个 return 语句,因为基本上当它从函数堆栈中弹出时,它期望从之前的调用中得到一些值.

我有一些用于插入 BST 的代码

insertCorrectLocation(root, newNode) {
    if (newNode.data < root.data) {
        if (root.left == null) {
            root.left = newNode
        } else {
            return this.insertCorrectLocation(root.left, newNode)
        }
    }
    else {
        if (root.right == null) {
            root.right = newNode
        } else {
            return this.insertCorrectLocation(root.right, newNode)
        }
    }
}

即使我删除了调用的返回语句,这也有效,例如

else {
    if (root.right == null) {
        root.right = newNode
    } else {
        this.insertCorrectLocation(root.right, newNode)
    }
}

这是怎么发生的?

【问题讨论】:

    标签: javascript algorithm recursion binary-search-tree


    【解决方案1】:

    我同意在递归函数中不需要显式返回的所有说法。

    但我目前正在研究一个巨大的递归函数,大约 600 行,其中包含许多 if-else 语句。我认为长递归函数不显式返回可能很危险。虽然我知道长递归函数还有其他问题,但仅使用 return; 并没有什么坏处,尤其是意图。

    【讨论】:

    • 我不明白return 与“长”递归函数的安全性有何关系。如果逻辑太混乱以至于您不得不折腾return“以防万一”您有控制流错误,则需要简化功能。 OP 询问为什么某些递归函数即使没有return 也能工作,而另一些则需要return,原因是这种情况下的算法逻辑不依赖于子结果或返回值。它就地改变树,每个调用帧只关心参数,而不关心返回值。
    【解决方案2】:

    没有要求return 来自主要用于副作用的函数的任何值。递归函数没有特殊处理,因此也适用于那些。例如。 console.log主要用于效果,返回默认值undefined。因此,在您的示例中,递归函数更改现有对象将能够在过程完成后将根节点用作整个树。

    最常见的错误是合约应该返回一个值,而您在某些地方忘记了返回。例如。

    function factorial(n) {
      if (n === 1) return 1;
    
      factorial(n - 1) * n;
    }
    
    factorial(1) ; //==> 1
    factorial(2) ; //==> undefined
    

    没有显式返回值的函数总是返回undefined。因此,对于返回undefined 的阶乘,显然是一个错误,但它确实倒回了堆栈并进行了所有计算,只是它没有使用结果。

    【讨论】:

      【解决方案3】:

      在递归函数中,如果递归函数的外层consumer需要接收值,则只需要(显式)return,例如:

      const foundNode = tree.findNode(5);
      

      在这种情况下,由于您只是插入一个值,而不是检索一个值,因此不需要递归 returns。

      (如果没有return 语句,函数将在到达其块末尾时自动返回,将控制权交还给调用者)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多