理解合并堆应用树折叠进行堆排序

时间:2018-01-17 03:47:18

标签: haskell functional-programming fold heapsort

请帮助我理解下面的代码。我明白了

map heapify

适用于输出

 map heapify [34,25,28]
[Node 34 [],Node 25 [],Node 28 []]

现在我将如何逐步理解这个表达。

merge_heaps = treefold merge_heap Nil

通过单独执行merge_heap来尝试这一点。

merge_heap Nil . map heapify [34,25,28]

错误

<interactive>:13:18: error:
    * Couldn't match expected type `a -> Heap a1'
                  with actual type `[Heap Integer]'

如何解释左折叠树结构以生成最大堆。击中。我将如何进一步逐步理解。

如何在命令式语言中映射我对堆排序的理解,从功能意义上的维基百科中排序。如何对不平衡树折叠结构进行堆排序。

-- treefold (*) z [a,b,c,d,e,f] = (((a*b)*(c*d))*(e*f))
treefold f zero [] = zero
treefold f zero [x] = x
treefold f zero (a:b:l) = treefold f zero (f a b : pairfold l)
    where
        pairfold (x:y:rest) = f x y : pairfold rest
        pairfold l = l -- here l will have fewer than 2 elements

data Heap a = Nil | Node a [Heap a] deriving Show
heapify x = Node x []

heapsort :: Ord a => [a] -> [a]
heapsort = flatten_heap . merge_heaps . map heapify
    where
        merge_heaps :: Ord a => [Heap a] -> Heap a
        merge_heaps = treefold merge_heap Nil

        flatten_heap Nil = []
        flatten_heap (Node x heaps) = x:flatten_heap (merge_heaps heaps)

        merge_heap :: Ord a => []
        merge_heap heap Nil = heap
        merge_heap node_a@(Node a heaps_a) node_b@(Node b heaps_b)
            |  a < b = Node a (node_b: heaps_a)
            | otherwise = Node b (node_a: heaps_b)

1 个答案:

答案 0 :(得分:3)

您遇到的具体错误,

<interactive>:13:18: error:
    * Couldn't match expected type `a -> Heap a1'
                  with actual type `[Heap Integer]'

是因为您的测试表达式merge_heap Nil . map heapify [34,25,28]是haskell语法对heapsort定义(部分)的错误扩展。

您想将功能merge_heaps . map heapify应用于[34,25,28]。你不能通过连接字符串来做到这一点。在Haskell中,空格的函数应用程序总是优先于任何二元运算符。

您的代码被解析为merge_heaps . (map heapify [34,25,28]),这是一个类型错误,因为带括号的子表达式不是函数。您需要(merge_heaps . map heapify) [34,25,28]merge_heaps (map heapify [34,25,28])甚至merge_heaps . map heapify $ [34,25,28]之类的内容。也许不是现在的最后一个。当你还在学习语法和类型时,这可能会令人困惑。

我认为merge_heaps (map heapify [34,25,28])很容易就是最简单的 - 它会删除所有运算符。暂时坚持下去。