尝试验证二叉树是二叉搜索树

问题描述

我正在学习二叉搜索树,尝试这个问题二叉树是二叉搜索树还是不是?

通过进行中序遍历,我想检查它是否按升序排列,

def isBst(self,root,prev = None):
        if root is not None:
            
            self.isBst(root.left,prev)
            if prev != None and root.data <= prev.data:
                return False
            prev = root
            self.isBst(root.right,prev)
        else:
            return True

在这里,我试图将每个中序遍历存储在 prev 变量中,并使用 prev 检查下一个遍历,如果它小于这意味着它不是 BST ,否则它将返回 True。这就是我想要做的。但在这里我正在尝试这样做,但我不明白我在这里做什么?它不给任何作为输出

有人可以告诉我并帮助我理解这一点吗?

解决方法

一些问题:

  • 函数可以返回None,因为if块没有以return语句结束,所以会返回默认的None

  • 主要问题是您没有使用递归调用的返回值。想象一下,递归调用返回 False,这意味着某处违反了 BST 属性……然后您的代码将忽略该消息并继续处理树的其余部分。所以你至少应该考虑返回值——像这样(但请参阅下一个要点):

    valid = self.isBst(root.left,prev)
    if not valid:
        return False
    # ... other code...
    return True
    
  • 您似乎假设递归调用会修改调用者的 prev 变量的值,但这是不可能的。当您将 prev 作为参数传递时,您不会传递 变量,而是传递该变量所具有的值,并且递归执行上下文会创建其自己的 prev 变量,该变量以与提供的价值。但是对那个变量的任何赋值都与调用者的prev变量无关。

与其尝试解决这些问题,我还建议采用一种不同的方法,我发现这种方法也更直观:在单独的函数中创建一个有序迭代器:一个只处理 yielding 一个接一个的值......仅此而已。然后,实际的 isBst 函数可以迭代该迭代器并轻松检测违规。

效果如下:

class Solution:
    def traverse(self,root):
        if root:
            yield from self.traverse(root.left)
            yield root.data
            yield from self.traverse(root.right)

    def isBst(self,root):
        inorder = self.traverse(root)
        prev = next(inorder,None)  # smallest
        for value in inorder:  # the rest...
            if prev > value:
                return False
            prev = value
        return True

使用 itertools.tee,您可以将 isBst 代码缩短一点:

    def isBst(self,root):
        import itertools
        # get two inorder iterators on the tree's values
        iprev,icurr = itertools.tee(self.traverse(root))
        # advance one of the two
        next(icurr,None)
        # check the pairs by consuming both iterators in tandem
        return all(prev <= curr for prev,curr in zip(iprev,icurr))

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...