【问题标题】:How to find the node that holds the minimum element in a binary tree in Haskell?如何在Haskell中找到包含二叉树中最小元素的节点?
【发布时间】:2014-12-16 07:38:24
【问题描述】:

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

给定一个数据类型

data (Ord a, Eq a) => Tree a = Nil | Node (Tree a) a (Tree a) 

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

我正在尝试递归思考:最小值是左、右子树和当前值之间的最小值。但是,我正在努力将其转换为 Haskell 代码。我面临的问题之一是我想返回树而不仅仅是值。

【问题讨论】:

  • 创建一个Foldable 实例和fold 和min。

标签: haskell tree


【解决方案1】:

这里有一个提示:

您可以首先定义两棵树之间的最小值作为辅助函数。 Nodes 根据其值进行比较,忽略子树,并将 Nil 与任何树 t 进行比较使 t 成为最小值(在某种意义上,我们将 Nil 视为“最大”树) .编码可以通过案例来完成:

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】:

    注意: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 约束。我认为您甚至不太可能为此使用==。

    【讨论】:

    • 对不起,我还是很困惑。实际上,在阅读您的答案之前,我得出结论认为我需要处理这些基本案例,但是,我现在真的不知道如何编写代码。例如,“getMinTree'(Node Nil value right)”的情况意味着我们只需要将这个节点与权利进行比较;但我不确定如何实现它。
    • @chi 谢谢。我想我已经修好了,但我会在我到电脑前进行测试。
    • @user35477,概念是将子树与其最小节点配对。
    • s/it's/its/@dfeuer
    • @jdlugosz,尽管这个错误很尴尬,但我现在无能为力。
    【解决方案3】:

    你有正确的理解。当你能证明以下几点时,我认为你应该没问题:

    • 最小的树可以是Nil
    • 具有 min 的树可能在根处具有 min 值

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

    你没有提到函数的类型是什么。所以,让我们假设它看起来像这样:

    findmin :: Tree a -> Tree a
    

    现在,假设您已经有一个查找树的 min 的函数。比如:

    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
    

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

    除了给出实际代码之外很难给出答案,因为你的想法已经是正确的。

    【讨论】:

    • 您所说的“可能在根节点处具有最小值”是什么意思?在这种情况下,这听起来不太可能是正确的,因为没有关于元素如何在树中排列的信息。
    • @dfeuer 我认为这就是OP所说的“归还树”的意思
    猜你喜欢
    • 2021-05-17
    • 1970-01-01
    • 2014-03-05
    • 1970-01-01
    • 1970-01-01
    • 2019-04-16
    • 1970-01-01
    • 1970-01-01
    • 2017-01-20
    相关资源
    最近更新 更多