我试图解决类似的问题(找到列表树中最短的列表),我认为解决这个问题将是一个良好的开端。
给定类似
的数据类型data (Ord a, Eq a) => Tree a = Nil | Node (Tree a) a (Tree a)
如何找到上面二叉树中包含最小元素的节点? 请注意,这不是二叉搜索树。
我试图递归思考:最小值是左,右子树和当前值之间的最小值。但是,我很难将其转换为Haskell代码。我面临的一个问题是我想要返回树而不仅仅是值。
答案 0 :(得分:1)
注意:Haskell 2010不再支持对数据类型声明的类约束,通常不建议这样做。所以这样做:
data Tree a = Nil
| Node (Tree a) a (Tree a)
递归思考:
getMinTree :: Ord a => Tree a -> Maybe (Tree a)
getMinTree = snd <=< getMinTree'
getMinTree' :: Ord a => Tree a -> Maybe (a, Tree a)
getMinTree' Nil = ???
getMinTree' (Node Nil value Nil) = ???
getMinTree' (Node Nil value right) = ???
getMinTree' (Node left value Nil) = ???
getMin' (Node left value right) = ???
另请注意:不需要Eq
约束。由于Eq
是Ord
的超类,Ord
约束意味着Eq
约束。我不认为您甚至可能会使用==
。
答案 1 :(得分:1)
这里有一个提示:
您可以从仅定义两棵树之间的最小值作为辅助函数开始。 Node
根据值进行比较,忽略子树,并将Nil
与任何树t
进行比较,使t
最小化(从某种意义上说,我们会想到{{}} Nil
1}}作为&#34;最大的&#34;树)。编码可以通过以下情况来完成:
binaryMin :: Ord a => Tree a -> Tree a -> Tree a
binaryMin Nil t = t
binaryMin t Nil = t
binaryMin (Node l1 v1 r1) (Node l2 v2 r2) = ???
然后,最小子树后跟递归,利用binaryMin
:
treeMin :: Ord a => Tree a -> Tree a
treeMin Nil = Nil
treeMin (Node left value right) = ???
where l = treeMin left
r = treeMin right
答案 2 :(得分:0)
您有正确的理解。当你证明以下事项时,我认为你应该没事:
Nil
因此,您可能需要对子树进行模式匹配以获取根节点的值,而不是仅仅比较值。
您没有提到该功能的类型。所以,我们假设它看起来像这样:
findmin :: Tree a -> Tree a
现在,假设您已经有一个找到树的最小值的函数。类似的东西:
findmin Nil = Nil -- no tree - no min
findmin (Node l x r) = case (findmin ..., findmin ...) of
-- like you said, find min of the left, and find min of the right
-- there will be a few cases of what the min is like on the left and right
-- so you can compare them to x
some case -> how to find the min in this case
some other case -> how to find min in that other case
也许,你需要知道前两个问题的答案。
由于你的想法已经是正确的,所以很难给出答案而不是泄露实际的代码。