繁体   English   中英

一次验证可比对象的二进制搜索树

[英]Validate binary search tree of comparables in a single pass

验证二进制搜索树的常用算法是递归检查每个值是否在有效数字范围内,然后在每个节点上将该范围分成两部分。

一些示例Python可以说明该算法(对于非重复值):

def walker(node, low, high):
    if node is None:
        return True
    if not (low < node.data < high):
        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, -2**32, 2**32)

这假设值是整数,并且它们都在(-2^32, 2^32)

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

对于平衡的树,它可以在O(2*log n + 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)

由于我们假设minimum least(root)给我们树中的最小值,而most(root)给我们最大值,所有其他值应在(least(root), most(root))

如果树无效,则树中某处会有一个较小的值s ,使s < least(root) ,和/或树中某处会有一个较大的值l ,以使most(root) < l 这些方法中的任何一个都将失败(low < node.data < high)验证步骤。

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

在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

None被认为是不可排序的。 不管是什么(例如,使用另一种编程语言),那么您只需要发明一个系统(例如,传递附加参数),即可指定下限或上限是活动的

例如,您可以定义四种方法来定义树,例如:

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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM