如何知道不规则树的最大值?

时间:2015-02-02 22:36:43

标签: haskell

我有一个不规则定义的树,我如何通过它来找到它的最大值?

我的策略是建立一个列表并取出更大的价值,我的问题是,我只知道二叉树,我有左边和右边,像这样:Node x Empty Empty

我现在有这个结构:

tree= No 2 [No 3 [No 6 []], No 4 [No 7 [], No 8 []], No 5 []]

data TreeIrr a = No a [TreeIrr a]

它应该如何遍历?

这是我能做的最好的事情:

maxi :: ArvIrr a -> [a]
maxi (No a []) = [a]
maxi (No a l@((No b []):z)) = [a]++[b]++(maxis l)
                    where
                     maxis ((No x k):(No y z):ls) = [y]++maxis ls
maxi (No a [k]) = [a]++(maxi k)

3 个答案:

答案 0 :(得分:4)

data TreeIrr a = No a [TreeIrr a]

这种树的最大元素是两个值中的最大值:

  1. 根音符中的元素。
  2. 子女最大值的最大值。
  3. 因此:

    treeMaximum :: Ord a => TreeIrr a -> a
    treeMaximum (No a []) = a
    treeMaximum (No a children) = max a (maximum (map treeMaximum children))
    

    max :: Ord a => a -> a -> amaximum :: Ord a => [a] -> a是标准库函数。

答案 1 :(得分:3)

让我们假装我们有一个遍历函数:

maxi :: ArvIrr a -> [a]

我们应该如何将其扩展到树的列表

maxiList :: [ArvIrr a] -> [a]

好吧,我们可以使用map

maxiList l = map maxi l  -- WRONG type [[a]]

但是我们得到的是列表而不是单个列表。没问题,让我们把它们连接起来。

maxiList l = concat (map maxi l)

好的,现在让我们假设我们maxiList正在工作,并根据它构建maxi。这很简单:

maxi (No a l) = a : maxiList l

所以,把所有东西放在一起:

maxi :: ArvIrr a -> [a]
maxi (No a l) = a : maxiList l
maxiList :: [ArvIrr a] -> [a]
maxiList l = concat (map maxi l)

我们可以通过删除maxiList并内联它来进一步简化它。

maxi :: ArvIrr a -> [a]
maxi (No a l) = a : concat (map maxi l)

并且concat (map maxi l)可以重写为concatMap maxi l, 利用concatMap库函数。

maxi :: ArvIrr a -> [a]
maxi (No a l) = a : concatMap maxi l

要计算最大值,您可以使用

maxInTree :: Ord a => ArvIrr a -> a
maxInTree t = maximum (maxi t)

如果需要,可以进一步简化此代码,以便甚至不构建中间列表,并直接计算最大值。对于Haskell初学者来说这可能有点挑战,但它可能很有趣。首先,在上面的代码中替换concat ...

答案 2 :(得分:2)

只需使用简单的递归式dfs遍历:

data TreeIrr a = No a [TreeIrr a]

findMax :: Ord a => TreeIrr a -> a
findMax (No x []) = x     -- For a tree without subtrees the maximum is it's value
findMax ( No x subtrees ) =
    maximum ( x : map findMax subtrees)      -- For a tree with subtrees the maximum is the maximum among it's root value or the maximum of it's subtrees

然后

>> findMax (No 2 [No 3 [No 6 []], No 4 [No 7 [], No 8 []], No 5 []])
8

UPD:  经过一番思考后,基本情况在这里是多余的。所以 只是

findMax :: Ord a => TreeIrr a -> a
findMax ( No x subtrees ) = maximum ( x : map findMax subtrees)

可以正常使用