Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Haskell的二叉树中找到包含最小元素的节点?_Haskell_Tree - Fatal编程技术网

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

如何在Haskell的二叉树中找到包含最小元素的节点?,haskell,tree,Haskell,Tree,我正在尝试解决一个类似的问题(在列表树中找到最短的列表),我认为解决这个问题将是一个良好的开端 给定一个数据类型,如 data (Ord a, Eq a) => Tree a = Nil | Node (Tree a) a (Tree a) 如何在上面的二叉树中找到包含最小元素的节点? 请注意,这不是一个二进制搜索树 我试着递归地思考:最小值是左、右子树和当前值之间的最小值。然而,我正在努力将其转换为Haskell代码。我面临的一个问题是,我想返回树,而不仅仅是值。您的理解是正确的。如

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

给定一个数据类型,如

data (Ord a, Eq a) => Tree a = Nil | Node (Tree a) a (Tree a) 
如何在上面的二叉树中找到包含最小元素的节点? 请注意,这不是一个二进制搜索树


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

您的理解是正确的。如果你能证明以下几点,我认为你应该没事:

  • 最小值为
    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
也许,你需要知道前两个问题的答案


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

注意: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) = ???
getMinTree::Ord a=>树a->Maybe(树a)
getMinTree=snd树a->可能(a,树a)
getMinTree'无=???
getMinTree'(节点Nil值Nil)=???
getMinTree'(节点零值右)=???
getMinTree'(节点左值Nil)=???
getMin'(节点左值右)=???
另请注意:不需要
Eq
约束。由于
Eq
Ord
的超类,
Ord
约束意味着
Eq
约束。我认为你甚至不可能用
=
来做这件事。

这里有个提示:

首先,可以定义两棵树之间的最小值作为辅助函数
Node
s根据其值进行比较,忽略子树,将
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

你所说的“可能在根上有最小值”是什么意思?在这种情况下,这听起来不太可能是正确的,因为没有关于元素在树中如何排列的信息。@dfeur我想这就是OP所说的“返回树”的意思,对不起,但我仍然感到困惑。事实上,在阅读您的答案之前,我得出结论,我需要处理这些基本情况,然而,我现在真的不知道如何编写代码。例如,“getMinTree”(Node Nil value right)意味着我们只需要将这个节点与right进行比较;但我不知道如何实施它。@chi谢谢。我想我已经修好了,但当我到我的电脑前我会测试。@user35477,这个概念是将子树与其最小的节点配对。
s/it's/its/
@dfeuer@jdlugosz,尽管这个错误很尴尬,但我现在无法修复它。创建一个实例并用
min
折叠