如何在Haskell中找到包含二进制树中最小元素的节点?

时间:2014-10-21 06:53:49

标签: haskell tree

我试图解决类似的问题(找到列表树中最短的列表),我认为解决这个问题将是一个良好的开端。

给定类似

的数据类型
data (Ord a, Eq a) => Tree a = Nil | Node (Tree a) a (Tree a) 

如何找到上面二叉树中包含最小元素的节点? 请注意,这不是二叉搜索树。

我试图递归思考:最小值是左,右子树和当前值之间的最小值。但是,我很难将其转换为Haskell代码。我面临的一个问题是我想要返回树而不仅仅是值。

3 个答案:

答案 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约束。由于EqOrd的超类,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)

您有正确的理解。当你证明以下事项时,我认为你应该没事:

  • min为Nil
  • 的树
  • 带有min的树可能在根
  • 处具有最小值

因此,您可能需要对子树进行模式匹配以获取根节点的值,而不是仅仅比较值。

您没有提到该功能的类型。所以,我们假设它看起来像这样:

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

也许,你需要知道前两个问题的答案。

由于你的想法已经是正确的,所以很难给出答案而不是泄露实际的代码。