我有一个练习面试问题告诉我要验证一棵树是否是一个平衡的搜索树,并给出一个验证方法......我的课程为
Class Node:
def __init__(self, k, val):
self.key = k
self.value = val
self.left = None
self.right = None
和树的最大值和最小值的其他函数定义为
def tree_max(node):
maxleft = float('-inf') if not node.left else tree_max(node.left)
maxright = float('-inf') if not node.right else tree_max(node.right)
return max(node.value, maxleft, maxright)
def tree_min(node):
minleft = float('-inf') if not node.right else tree_min(node.left)
minright = float('-inf') if not node.left else tree_min(node.right)
return min(node.value, minleft, minright)
我的验证方法为
def verify(node):
if tree_max(node.left) <= node.value and node.value <= tree_min(node.right):
if verify(node.left) and verify(node.right):
return True
else:
return False
else:
return False
当我尝试实现验证方法时,我的问题就出现了,即使我尝试制作BST树,我似乎也总是假的。我的实现如下:
root= Node(10, "Hello")
root.left = Node(15, "Fifteen")
root.right= Node(30, "Thirty")
print verify(root)
root = Node(10, "Ten")
root.right = Node(20, "Twenty")
root.left = Node(5, "Five")
root.left.right = Node(15, "Fifteen")
print verify(root)
两者都给我错误......我的验证功能或我的最小/最大功能是否有问题......任何帮助都将不胜感激。
答案 0 :(得分:8)
我在您的代码中看到了四个错误。
首先,检查空子项是tree_min
的后退。也就是说,您在访问node.right
之前检查node.left
是否存在,反之亦然。
其次,tree.min
在叶子节点上调用时返回负无穷大。您需要在最小计算中使用正无穷大(负无穷大在最大版本中是正确的)。
第三,你在verify
内有一个逻辑错误,因为它无条件地调用tree_min
或tree_max
及其自身的子节点,即使其中一个或两个都是None
。我建议让所有函数句柄都被传递None
,而不是依赖调用者来做正确的事情。这也简化了min
和max
代码!
最后,您正在对node.value
进行比较,这是您为每个节点提供的字符串。我怀疑你想用node.key
进行比较。将float(如float("-inf")
)与字符串(如"ten"
)进行比较是Python 3中的一个错误,即使在合法的Python 2中,它也可能不像您期望的那样工作。
修复这些问题后,当我创建有效和无效的树时,我得到了预期的结果。您的两个示例都是无效的,因此如果您使用它们进行测试,您将始终获得False
结果。
最后,还有一些小问题(不是错误,但仍然可以改进)。 Python支持链式比较,因此您可以将if
中的第一个verify
语句简化为tree_max(node.left) <= node.key <= tree_min(node.right)
。您可以通过将检查与and
连接,而不是嵌套其他if
语句来进一步简化代码的这一部分。
这是一个适合我的代码版本(使用Python 3,虽然我认为它向后兼容Python 2):
class Node:
def __init__(self, k, val):
self.key = k
self.value = val
self.left = None
self.right = None
def tree_max(node):
if not node:
return float("-inf")
maxleft = tree_max(node.left)
maxright = tree_max(node.right)
return max(node.key, maxleft, maxright)
def tree_min(node):
if not node:
return float("inf")
minleft = tree_min(node.left)
minright = tree_min(node.right)
return min(node.key, minleft, minright)
def verify(node):
if not node:
return True
if (tree_max(node.left) <= node.key <= tree_min(node.right) and
verify(node.left) and verify(node.right)):
return True
else:
return False
root= Node(10, "Hello")
root.left = Node(5, "Five")
root.right= Node(30, "Thirty")
print(verify(root)) # prints True, since this tree is valid
root = Node(10, "Ten")
root.right = Node(20, "Twenty")
root.left = Node(5, "Five")
root.left.right = Node(15, "Fifteen")
print(verify(root)) # prints False, since 15 is to the left of 10