[英]Trying Validate a Binary Tree is Binary Search Tree
我正在学习二叉搜索树,并尝试这个问题 二叉树是二叉搜索树还是不是?
通过进行中序遍历,我想检查它是否按升序排列,
def isBst(self,root,prev = None):
if root is not None:
self.isBst(root.left,prev)
if prev != None and root.data <= prev.data:
return False
prev = root
self.isBst(root.right,prev)
else:
return True
在这里,我试图将每个中序遍历存储在 prev 变量中,并使用 prev 检查下一次遍历,如果它小于这意味着它不是 BST ,否则它将返回 True。 这就是我想要做的。 但在这里我正在尝试这样做,但我不明白我在这里做什么? 它不给任何作为输出。
任何人都可以告诉我并帮助我理解这一点吗?
一些问题:
函数可以返回None
,因为if
块没有以return
语句结束,所以会返回默认的None
主要问题是您不使用递归调用的返回值。 想象一下,递归调用返回 False,这意味着在某处违反了 BST 属性……然后您的代码将忽略该消息并继续处理树的其余部分。 所以你至少应该考虑返回值——像这样(但请参阅下一个要点):
valid = self.isBst(root.left, prev) if not valid: return False # ... other code... return True
您似乎假设递归调用会修改调用者的prev
变量的值,但这是不可能的。 当您将prev
作为参数传递时,您不会传递变量,而是传递该变量具有的值,并且递归执行上下文会创建自己的prev
变量,该变量以该提供的值开始。 但是对该变量的任何赋值都与调用者的prev
变量无关。
我不会尝试解决这些问题,而是建议采用一种不同的方法,我发现使用这种方法也更直观:在单独的函数中创建一个有序迭代器:一个只处理一个接一个产生一个值的函数。 . 仅此而已。 实际的isBst
函数然后可以迭代该迭代器并轻松检测违规。
这是它的外观:
class Solution:
def traverse(self, root):
if root:
yield from self.traverse(root.left)
yield root.data
yield from self.traverse(root.right)
def isBst(self, root):
inorder = self.traverse(root)
prev = next(inorder, None) # smallest
for value in inorder: # the rest...
if prev > value:
return False
prev = value
return True
使用itertools.tee
你可以让isBst
代码更短一点:
def isBst(self, root):
import itertools
# get two inorder iterators on the tree's values
iprev, icurr = itertools.tee(self.traverse(root))
# advance one of the two
next(icurr, None)
# check the pairs by consuming both iterators in tandem
return all(prev <= curr for prev, curr in zip(iprev, icurr))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.