有关BST递归的困惑

问题描述

有什么简单的方法可以理解何时可以调用递归方法而不是将递归方法设置为变量?

例如...
只需调用递归函数即可遍历:
self.recurse(node.left)
self.recurse(node.right)

必须将递归函数设置为node.left和node.right:
node.left = self.recurse(node.left)
node.right = self.recurse(node.left)

另一个示例是首先删除一个节点,然后将递归函数设置为root.left和root.right ...我明白了,但还不完全是...有什么简单的方法可以理解何时只需调用递归函数,而不必将其设置为node.left,node.right..etc ...?

def deleteNode(self,root: TreeNode,key:int) -> TreeNode:
    
    if not root:
        return root
    if key < root.val:
        root.left = self.deleteNode(root.left,key)
    elif key > root.val:
        root.right = self.deleteNode(root.right,key)
    else:
        if not root.left:
            return root.right
        elif not root.right:
            return root.left
        
        root.val = self.successor(root.right)
        root.right = self.deleteNode(root.right,root.val)
    
    return root

解决方法

要了解以上两种情况(简单递归调用和对变量的递归调用的Set结果),只需尝试了解以下代码/函数即可。

比方说,您有一个树,该树在每个值为负或正的节点中都包含一个值。现在,假设您要计算有多少个值为“正”的节点。 此问题的TREE结构如下:

TREE{
  Integer val;
  TREE left = right = null;
}

现在您给了我这个问题来解决。我写了一个函数/方法,它将对具有正值的节点进行计数。该函数如下:

Integer countNodes(TREE node){
  if(node == null){
     return 0;
  }else{
      Integer count = 0; // which will count how many nodes are there with positive value
      if(node.val >= 0){
         count += 1; // if the value is positive I incremented count
      }

      // and we are checking every other nodes present in the TREE
      getCount(node.left);
      getCount(node.right);

     // and return the final result
     return count;
  }
}

现在我将函数返回给您,您执行了!但是什么!有很大的错误!一遍又一遍地给出错误的结果!

但是为什么?

让我们分析。

 if(node.val >= 0){
     count += 1;
 }

到目前为止,我们是对的!但是问题是,我们增加了计数,但没有使用它!每次我们递归调用函数时,都会创建一个新的堆栈框架,并创建一个名为“ count”的新变量,但是我们并没有使用该值!

要使用变量“ count”,我们需要重新初始化对该变量的每个递归调用的返回值,这是我们可以在当前堆栈帧与先前堆栈帧之间保持链接的方式。我们需要更改countCounts函数中的小位,如下所示:

  if(node.val >= 0){
      count += 1;
  }

  count += getCount(node.left);  // re-initialize count in each recursive call
  count += getCount(node.right); // re-initialize count in each recursive call

  return count;

现在一切都会好起来的!该代码将完美运行!

以上情况暗示您有问题。

self.recurse(node.left)

self.recurse(node.right)

这不过是简单遍历所有节点而已。

但是,如果您需要使用每次递归的返回结​​果,则需要将返回的值初始化/重新初始化为变量。这就是发生了什么:

node.left = self.recurse(node.left)

node.right = self.recurse(node.left)

我希望这个较长(有点长)的解释将有助于进一步发展。编码愉快! :)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...