检查树是否是二叉搜索树(BST)

时间:2017-07-03 12:21:43

标签: python python-3.x tree binary-search-tree

我正在尝试解决二叉搜索树问题,但我无法通过所有测试用例。如果树是二叉搜索树,我需要返回true,否则,我需要返回false。谁能告诉我我做错了什么?

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

def checkBST(root):
    if root.left == None and root.right == None:
        return True
    if root == None:
        return True
    if root.left != None:
        if root.left.data < root.data:
            return True
    else:
        return False
    if root.right != None:
        if root.right.data > root.data:
            return True
        else:
            return False
    return chckBST(root.left) and chckBST(root) and chckBST(root.right)

2 个答案:

答案 0 :(得分:4)

您的代码中存在大量冗余if条件。您可以像这样简化它:

def checkBST(root):
    if root == None or (root.left == None and root.right == None):
        return True

    elif root.right == None:
        return root.left.data < root.data and checkBST(root.left)

    elif root.left == None:
        return root.right.data >= root.data and checkBST(root.right)

    return checkBST(root.left) and checkBST(root.right)

首先,检查所有None条件。 python中的短路保证如果第一个条件是False,则不会评估第二个条件。这允许您编写简洁的语句,例如return root.left.data < root.data and checkBST(root.left)

最后,如果左侧和右侧节点都不是None,请再次呼叫checkBST(root)。这导致无限递归。

答案 1 :(得分:0)

因此,您未通过某些测试的原因是因为您只检查了一个级别。例如,如果tree存在root.left.right.data&gt; root.data,那么你的代码就不会抓住它。有一个很好的解释here

但要点是:

  • 您的代码将通过此

All left children are smaller and all right children are bigger

  • 但它没有通过注意2&gt;的正确孩子root.data

我认为这个解决方案解决了这个问题(很抱歉用JS代码回答了Python问题,但我确信你会得到这个想法):

function checkBST(root) {
    let isBST = true;
    let BSTUtil = r => {
        let left, right
        if(r.left) // Bottom out on the left side
            left = BSTUtil(r.left)
        if(r.right) // Bottom out on the right side
            right = BSTUtil(r.right)

        if(left > r.data) // Compare with parent
            isBST = false
        if(right < r.data) // Compare with parent
            isBST = false

        // Return MAX from branch
        if(!left && !right)
            return r.data
        else if(!left)
            return Math.max(right, r.data)
        else
            return Math.max(left, right, r.data)
    }
    BSTUtil(root)
    return isBST;
}

另外,请不要使用此代码,它会使用O(n)空间来解决问题,如果我花一些时间在这个问题上,我相信我能找到更有效的解决方案