【问题标题】:Confusion about recursion in a BST python关于 BST python 中递归的困惑
【发布时间】:2021-12-14 21:23:25
【问题描述】:

我试图理解二进制函数is_bst 中的递归调用。该函数的目标是检查一棵树是否是二叉搜索树。请注意,这只是完整功能的摘录。我试图了解is_bst 函数中的这段代码is_bst_l, min_l, max_l = is_bst(node.left) 上发生了什么。 is_bst 函数返回 (True, None, None),我试图通过递归地遍历函数来弄清楚函数是如何得出返回值的。 is_bst 函数将来自 parse_tuple 函数的二叉树节点作为输入。例如,当我尝试在is_bst 函数之外解压缩这行代码is_bst_l, min_l, max_l = node.left 时,我得到TypeError: cannot unpack non-iterable TreeNode object,但在函数内部,我没有收到错误消息。我的问题是

  1. is_bst 函数中递归发生了什么。
  2. 如何在is_bst 函数中不获取解包类型错误。

`

#Tree Class
class TreeNode:
    def __init__(self, key):
        self.key = key
        self.left = None
        self.right = None

#function converts a turble to a binary tree
 def parse_tuple(data):
    # print(data)
    if isinstance(data, tuple) and len(data) == 3:
        node = TreeNode(data[1])
        node.left = parse_tuple(data[0])
        node.right = parse_tuple(data[2])
    elif data is None:
        node = None
    else:
        node = TreeNode(data)
    return node

函数检查一棵树是否是二叉搜索树。

def remove_none(nums):
return [x for x in nums if x is not None]

def is_bst(node):
    if node is None:
        return True, None, None
    
    is_bst_l, min_l, max_l = is_bst(node.left)
    is_bst_r, min_r, max_r = is_bst(node.right)
    is_bst_node = (is_bst_l and is_bst_r and 
              (max_l is None or node.key > max_l) and 
              (min_r is None or node.key < min_r))
#     print('Minkey left: ', min_l, 'Nodekey :', node.key, 'Maxkey left: ',min_r)
#     print('Minkey left: ', max_l, 'Nodekey :', node.key, 'Maxkey left: ',max_r)
    min_key = min(remove_none([min_l, node.key, min_r]))
    max_key = max(remove_none([max_l, node.key, max_r]))
    
    # print(node.key, min_key, max_key, is_bst_node)
        
    return is_bst_node, min_key, max_key

#函数调用

my_tuple= ((None,3,None),2,(None,5,None))
node = parse_tuple(my_tuple)

【问题讨论】:

  • 它不是检查树是否是BST,你只是在遍历
  • @sahasrara62 是的,我明白,我只是想了解函数is_bst 中的递归调用。就像我在问题中提到的那样,is_bst 只是完整的is_bst 函数的摘录。
  • is_bst 函数在哪里完成?只是预购遍历
  • @sahasrara62 我已经用完整的is_bst 函数更新了问题

标签: python recursion binary-tree binary-search-tree


【解决方案1】:

该函数返回当前节点左右的最大和最小键(除了检查的真/假结果)。它的递归从左右节点组装这些密钥/有效性状态,从而创建需要管理(即排除)子节点返回值的无结果。

这过于复杂,可能不值得您花时间分析和理解。

我想你会发现这个更简单一点:

def is_bst(node,minKey=None,maxKey=None):
    if node is None: return True
    if minKey is not None and node.key<=minKey: return False
    if maxKey is not None and node.key>=maxKey: return False
    if not is_bst(node.left,minKey,self.key):   return False
    if not is_bst(node.right,self.key,maxKey):  return False
    return True

【讨论】:

  • 您的解决方案没有返回 minKey 和 maxKey
  • 为什么要这样? “该函数的目标是检查一棵树是否是二叉搜索树”。在任何实现中,这两个都是独立的(并且更简单)的功能。例如def minKey(self): return self.left.minKey() if self.left else self.key
【解决方案2】:

如果对每个节点递归,一棵树就是一个 BST:

  • 如果存在,它的左树就是 BST
  • 如果存在,它的右树是 BST
  • 左树的最大值,如果存在,必须小于节点的值
  • 右树的最小值,如果存在,必须大于节点的值

因此对于三个值的元组的返回值是有意义的:

  • 我是 BST 吗?
  • 我的子树中最小的节点是什么
  • 我的子树中最大的节点是什么。

【讨论】:

  • 我只是用完整的功能更新了问题。树不是BST,最小节点是2,最大节点是5。我只是想了解代码is_bst_l, min_l, max_l = is_bst(node.left)这行发生了什么。如果我的问题听起来很荒谬,请原谅我。
  • 正是我上面解释的。函数is_bst 返回三个值:查看每个return 语句,您将看到三个值。该行然后将这三个返回值分配给三个变量。
  • 我想我现在从你上面的解释开始明白了。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-16
  • 2021-09-23
  • 1970-01-01
  • 2022-06-15
  • 2022-01-05
相关资源
最近更新 更多