Efficient heaps in purely functional languages

后端 未结 9 1882
被撕碎了的回忆
被撕碎了的回忆 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 13:58

    Arrays in Haskell aren't as hugely inefficient as you might think, but typical practice in Haskell would probably be to implement this using ordinary data types, like this:

    data Heap a = Empty | Heap a (Heap a) (Heap a)
    fromList :: Ord a => [a] -> Heap a
    toSortedList :: Ord a => Heap a -> [a]
    heapSort = toSortedList . fromList
    

    If I were solving this problem, I might start by stuffing the list elements into an array, making it easier to index them for heap creation.

    import Data.Array
    fromList xs = heapify 0 where
      size = length xs
      elems = listArray (0, size - 1) xs :: Array Int a
      heapify n = ...
    

    If you're using a binary max heap, you might want to keep track of the size of the heap as you remove elements so you can find the bottom right element in O(log N) time. You could also take a look at other types of heaps that aren't typically implemented using arrays, like binomial heaps and fibonacci heaps.

    A final note on array performance: in Haskell there's a tradeoff between using static arrays and using mutable arrays. With static arrays, you have to create new copies of the arrays when you change the elements. With mutable arrays, the garbage collector has a hard time keeping different generations of objects separated. Try implementing the heapsort using an STArray and see how you like it.

提交回复
热议问题