Python代码检查给定的二叉树是否为BST

时间:2019-12-21 21:10:49

标签: python tree binary binary-search-tree

要解决此问题,我喜欢方法4中here中所述的InOrderTraversal方法

对于根的左子项的右子项大于根节点的情况,该代码不起作用。 示例:

        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"

1 个答案:

答案 0 :(得分:0)

我正在标记关键声明,以使解释更简单。

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

现在,我假设您已经通过每次递归调用获得了局部变量的流。我将跳过其他节点,直接跳转到值为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网站中提到的那样在本地传递。