Python 在一次过程中验证可比数据的二元搜索树

Python 在一次过程中验证可比数据的二元搜索树,python,algorithm,tree,binary-search-tree,python-3.x,Python,Algorithm,Tree,Binary Search Tree,Python 3.x,验证二叉搜索树的常用算法是递归检查每个值是否在有效数字范围内,并在每个节点上将该范围一分为二 一些示例Python演示了该算法(对于非重复值): def walker(节点、低、高): 如果节点为无: 返回真值 如果不是(低

验证二叉搜索树的常用算法是递归检查每个值是否在有效数字范围内,并在每个节点上将该范围一分为二

一些示例Python演示了该算法(对于非重复值):

def walker(节点、低、高): 如果节点为无: 返回真值 如果不是(低<节点数据<高): 返回错误 返回walker(node.left,low,node.data)和walker(node.right,node.data,high) def checkBST(根目录): 如果root为None: 返回真值 返回步行器(根,-2**32,2**32) 这假设值是整数,并且它们都在
(-2^32,2^32)
范围内

如果我想为任何具有可比性的类型编写此算法,该怎么办?通过对树进行另一次遍历,可以在线性时间内找到树中的最小值和最大值,但是有没有一种方法不需要两次完整遍历

对于平衡树,它可以在
O(2*logn+n)
时间内完成,这非常接近于一次传递

如果二叉搜索树是有效的,则通过沿着左子树走到最后,找到最小的元素

def least(node):
    if node.left is None:
        return node.data
    return least(node.left)
类似地,通过沿着右子树向下走到最后,可以找到最大的元素

def most(node):
    if node.right is None:
        return node.data
    return most(node.right)
由于我们假设
least(root)
为我们提供了树中的最小值,
most(root)
为我们提供了最大值,因此所有其他值都应该在
(least(root)、most(root))的范围内


如果树无效,则树中的某个位置将有一个较小的值
s
,例如
s
,和/或树中某个较大的值
l
,例如
most(root)
。其中任何一个都会使验证步骤失败。

不需要找到最小值和最大值。您可以简单地取消对树的各个部分的约束检查,而不使用下限或上限

在Python中,您可以简单地使用
None
对象或任何其他对象来表示下限或上限约束未激活。例如:

def walker(node, low = None, high = None):
    if node is None:
        return True
    if low is not None and low >= node.data:
        return False
    if high is not None and high <= node.data:
        return False
    return walker(node.left, low, node.data) and walker(node.right, node.data, high)

def checkBST(root):
    if root is None:
        return True
    return walker(root) # look ma, no parameters
def walker(node, low = None, high = None):
    if node is None:
        return True
    if low is not None and low >= node.data:
        return False
    if high is not None and high <= node.data:
        return False
    return walker(node.left, low, node.data) and walker(node.right, node.data, high)

def checkBST(root):
    if root is None:
        return True
    return walker(root) # look ma, no parameters
def lwalker(node, low):
    if node is None:
        return True
    if low >= node.data:
        return False
    return lwalker(node.right,low) and luwalker(node.left, low, node.data)

def uwalker(node, upper):
    if node is None:
        return True
    if upper <= node.data:
        return False
    return uwalker(node.left,upper) and luwalker(node.right, node.data, upper)

def luwalker(node, low, upper):
    if node is None:
        return True
    if low >= node.data or upper <= node.data:
        return False
    return luwalker(node.left,low,node.data) and luwalker(node.right,node.data, upper)

def checkBST(root):
    if root is None:
        return True
    return uwalker(root.left,root.data) and lwalker(root.right,root.data)