Efficient heaps in purely functional languages

后端 未结 9 1866
被撕碎了的回忆
被撕碎了的回忆 2021-01-30 13:42

As an exercise in Haskell, I\'m trying to implement heapsort. The heap is usually implemented as an array in imperative languages, but this would be hugely inefficient in purely

9条回答
  •  醉梦人生
    2021-01-30 14:08

    Jon Fairbairn posted a functional heapsort to the Haskell Cafe mailing list back in 1997:

    http://www.mail-archive.com/haskell@haskell.org/msg01788.html

    I reproduce it below, reformatted to fit this space. I've also slightly simplified the code of merge_heap.

    I'm surprised treefold isn't in the standard prelude since it's so useful. Translated from the version I wrote in Ponder in October 1992 -- Jon Fairbairn

    module Treefold where
    
    -- 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
    
    
    module Heapsort where
    import Treefold
    
    data Heap a = Nil | Node a [Heap a]
    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 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)
    

提交回复
热议问题