【问题标题】:Problem with Python code checking if a given Binary Tree is BSTPython代码检查给定二叉树是否为BST的问题
【发布时间】:2019-12-21 21:10:49
【问题描述】:

为了解决这个问题,我喜欢方法 4 中描述的 InOrderTraversal 方法 here

代码不适用于根左孩子的右孩子大于根节点的情况。 示例:

        9
     5    10
   4  11    12

有人可以帮我解决这个问题吗?我注意到当我打印 prev.data 时它只打印 3 个元素

class TreeNode:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None


def isBSTUtil(root, prev):
    if root!=None:
        if isBSTUtil(root.left,prev)==False:
            return False

        if prev!=None and prev.data>root.data:
            return False

        prev=root    
        return isBSTUtil(root.right,prev)
    return True

def isBST(root):
    prev = None
    return isBSTUtil1(root,prev)


if __name__ == "__main__":
    root = TreeNode(9)
    root.left = TreeNode(5)
    root.right  = TreeNode(10)
    root.left.left = TreeNode(4)
    root.left.right = TreeNode(11)
    root.right.right = TreeNode(12)    
    if isBST(root):
        print "is BST"
    else:
        print "Not a BST"

【问题讨论】:

    标签: python tree binary binary-search-tree


    【解决方案1】:

    我正在标记关键语句以使解释更简单。

    class TreeNode:
        def __init__(self, data):
            self.data = data
            self.left = None
            self.right = None
    
    
    def isBSTUtil(root, prev):
        if root!=None:          # statement 1
            if isBSTUtil(root.left,prev)==False:     # statement 2
                return False      # statement 3
    
            if prev!=None and prev.data>root.data:     #statement 4
                return False      # statement 5
    
            prev=root             # statement 6
            return isBSTUtil(root.right,prev)      # statement 7
        return True               # statement 8
    
    def isBST(root):
        prev = None
        return isBSTUtil1(root,prev)
    
    
    if __name__ == "__main__":
        root = TreeNode(9)
        root.left = TreeNode(5)
        root.right  = TreeNode(10)
        root.left.left = TreeNode(4)
        root.left.right = TreeNode(11)
        root.right.right = TreeNode(12)    
        if isBST(root):
            print "is BST"
        else:
            print "Not a BST"
    

    让我们跟踪每个函数调用的解决方案

    step 1: `isBST(root)` is called. Here root = 9
    step 2: `isBSTUtil(root, prev)` is called. Here root = 9, prev = None
    step 3: since root is not None, a recursive call is made to `isBSTUtil(root, prev)`. Now, root = 5 (left node of root 9), prev = None
    step 4: again, since root is not None, another recursive call is made to isBSTUtil(root, prev) with root = 4, prev = None
    step 5: root is not None here also, so one more recursive call is made to isBSTUtil(root, prev) with root = None (left of 4 is None), prev = None
    step 6: Now at this step, the condition 'if root!=None' (statement 1) fails and the program return True (statement 8)
    step 7: recursive call which was halted at step 4 resumes with statement 2 and this condition will fail as the return statement in step 6 was True
    step 8: statement 4 starts execution. statement 4 fails as 'prev' is not None. with the execution of statement 6 (prev=root), prev now has the value = 4
    

    现在,我假设您已经获得了每次递归调用的局部变量流。我将跳过其他节点并直接跳转到 value = 5 的节点

    step 1: At this point, after all the recursive calls, root = 5, prev = 5 (after execution of statement 6) and now recursive call to the right subtree is being made (statement 7)
    step 2: with this recursive call, now root = 11 (right child of 5) and prev = 5
    step 3: Now at this step statement 4 will execute as prev is not None anymore and the second condition here (prev.data>root.data) will fail as prev.data = 5 and root.data=11 at this point. Hence the statement 5 will never execute and it won't return False. And this is main reason of faulty behavior. Ideally, at this point, the statement should have returned False, which would make the output of the program correct. 
    

    现在我希望你有问题。您应该保留 prev 的全局副本,而不是像 geeksforgeeks 网站中提到的那样在本地传递它。

    【讨论】:

    • 感谢您的详细解释,但如果您在方法 4 中看到 geeksforgeeks,那么我使用的第二种方法是通过传递局部变量来避免静态变量。你觉得那边的python实现有问题吗?
    • 你能在不使用全局变量而只在递归中使用局部变量的情况下修复代码吗?
    • @VenkateshMarepalli 我建议在检查statement 4时使用每个节点的顺序后继而不是prev。对于上面的树,顺序遍历将是4 5 11 9 10 12。现在,节点11 的顺序后继节点将是9,现在statement 4 将返回True,最终输出应返回False。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-16
    • 1970-01-01
    • 2017-09-28
    • 2018-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多