当前位置: 首页 > 知识库问答 >
问题:

使用预序遍历验证二叉树

澹台华采
2023-03-14

我正在查看LeetCode问题98。验证二进制搜索树:

给定二叉树的,确定它是否是有效的二叉搜索树 (BST)。

有效的BST定义如下:

  • 节点的左子树仅包含键小于节点键的节点。
  • 节点的右子树仅包含键大于节点键的节点。
  • 左右子树也必须是二叉搜索树。

下面提供的用前序遍历验证二叉树属性的代码有什么问题?

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def isValidBST(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        def preorder(root):
        
            if root.left!=None:
                if root.left < root.val:
                    preorder(root.left)
                else:
                    return False
            
        
            if root.right!=None:
                if root.right>root.val:
                    preorder(root.right)
                else:
                    return False
       
    t= preorder(root)
    return t!=False

对于root=[2,1,3]的测试用例,它将返回False

共有2个答案

乜钱明
2023-03-14

几个问题:

>

  • root.left

    尽管当存在冲突时,preorder返回False,但进行递归调用的调用方忽略此返回值并愉快地继续。这是错误的。当递归调用返回<code>False</code>时,它应该停止遍历,并且它自己将<code>False</ccode>返回给调用方。

    不是主要问题,但由于preord返回False,在其余情况下,它应该更好地返回true,因此您可以确定preord返回布尔值,而不必处理或将返回值显式与False进行比较。

    该算法仅检查节点的直接子节点是否具有与父节点的值不冲突的值,但这不足以验证BST。左侧子树中的所有值都必须小于父树的值,不仅仅是左侧子树的值。所以即使上面的问题都解决了,这个算法也会错误地说这个BST是有效的:

      4
     /
    1
     \
      9  <-- violation  (because of 4)
    

    为了解决最后一点,您需要修改算法:意识到当您深入BST时,有效BST中的子树可以有一个值窗口:有一个下限和一个上限。在上面的示例中,节点1的右子节点只能有一个范围(1,4)内的值。

    下面是一个作为扰流板的实现:

    <code>类解决方案(对象):def isValidBST(self,root):defpreorder(root,low,high):返回不是root或(low

  • 岑畅
    2023-03-14

    只有当左子树有效时,才需要遍历右子树。

           def preorder(root):
                if root.left!=None:
                    if root.left < root.val:
                        preorder(root.left)
                    else:
                        return False
                
            
                if root.right!=None (and left-sub-tree is valid):
                    if root.right>root.val:
                        preorder(root.right)
                    else:
                        return False
    

    注意:我不会Python。在检查右子树时理解注释。

     类似资料:
    • 对于二叉搜索树:7为根,1为左子,10为右子。 我试过调试这个函数,看看它是如何工作的,但我似乎不能理解一件事。函数检查并看到1的左子项和右子项都为空后,它就移动到节点10,然后检查右子项是否为空。有人能解释一下递归模式,以及为什么方法在初始检查节点1后没有退出。

    • 我在研究一个重建二叉查找树的函数。我正试着先用手做。 说我有:pre-10,3,5,4,15,7,8,2,9,20 in-4,5,3,15,10,20,8,7,9,20 我弄不明白。我知道10必须是根,顺序序列中10左边的所有数字都必须在右边的子树中。 那会给我 4,5,3,15 15大于10,并且为了成为二叉查找树,左子树中的所有节点应该小于根。 这是否意味着这两个序列形成了一个无效的二叉搜索树

    • 为了上课,我必须创建一个状态对象的二叉树,每个状态对象包括一个居民对象的二叉树,这些居民对象组织住在每个州的人。我试图在一个给定的州中搜索最老的居民;然而,居民是按字母顺序组织在树中的,这对我的搜索毫无帮助。因此,我必须遍历整个居民树,更新保存最老的人的节点,并在树被完全遍历后返回它。我已经有了代码的第一部分,但是还停留在如何写递归的剩余部分。 状态树的方法: 然后是公共“包装器”状态树方法:

    • 中序遍历二叉树 按完全二叉树的层次遍历给出一棵二叉树的遍历序列(其中用0表示虚结点),要求输出该二叉树的深度及中序遍历该二叉树得到的序列。 输入格式: 首先输入一个整数T,表示测试数据的组数,然后是T组测试数据。每组测试数据首先输入一个正整数n(n≤1000),代表给出的二叉树的结点总数(当然,其中可能包含虚结点)。结点编号均为正整数,且各不相同。 然后输入n个正整数,表示按完全二叉树(即第1层1

    • 我正在学习如何使用Postorder遍历删除二叉树。我知道要删除一个节点,首先我们需要删除它的子节点,然后是节点本身,所以Postorder遍历最适合删除二叉树。我想使用Inorder遍历做同样的事情,一切都很好,但我不明白下面的代码是如何工作的?

    • 本文向大家介绍C#使用前序遍历、中序遍历和后序遍历打印二叉树的方法,包括了C#使用前序遍历、中序遍历和后序遍历打印二叉树的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了C#使用前序遍历、中序遍历和后序遍历打印二叉树的方法。分享给大家供大家参考。具体实现方法如下: 希望本文所述对大家的C#程序设计有所帮助。