如何使用BST的定义和BST的广义fold版本来检查BST是否有效?
data(Ord a, Show a, Read a) => BST a = Void | Node {
val :: a,
left, right :: BST a
} deriving (Eq, Ord, Read, Show)
fold :: (Read a, Show a, Ord a) => (a -> b -> b -> b) -> b -> BST a -> b
fold _ z Void = z
fold f z (Node x l r) = f x (fold f z l) (fold f z r)
这个想法是检查节点值是否大于左子树中所有值,并小于其右子树中所有值。这必须对树中的所有节点都成立。函数bstList
只需输出BST中(有序)值的列表。
当然,像这样的东西是行不通的:
--isBST :: (Read a, Show a, Ord a) => BST a -> Bool
isBST t = fold (\x l r -> all (<x) (bstList l) && all (>x) (bstList r)) (True) t
举个例子,将fold函数应用于节点19
会得到all (<19) (bstList True) && all (>19) (bstList True)
。
z
也必须更改为非布尔值。使其返回 (True, (+inf, -inf)) 或类似的内容。 无论如何,将树转换为列表的其他解决方案似乎更符合您实际需要的内容。 - hugomg