
Hi,
I checked the current Fibonacci Queue in Hackage DB:
http://hackage.haskell.org/packages/archive/pqueue-mtl/1.0.7/doc/html/src/Da...
And a history email for Okasaki in 1995:
http://darcs.haskell.org/nofib/gc/fibheaps/orig
The hardest part is how to consolidate all unordered binomial trees in
deleteMin.
In imperative implementation, there is a elegant algorithm introduced
in Chapter 20 of CLRS[1].
How to achieve it in Functional way is the key point of solve this
problem.
If we have a list of trees with rank [2, 1, 1, 4, 8, 1, 1, 2, 4], we
need first meld the trees with same rank, and recursively doing that
until there are no two trees with same rank. Here is a simple function
can do this:
consolidate:: (Num a)=>[a] -> [a]
consolidate xs = foldl meld [] xs where
meld :: (Num a)=>[a] -> a -> [a]
meld [] x = [x]
meld (x':xs) x = if x == x' then meld xs (x+x')
else x:x':xs
Generalize the `+` to link and `==` to compare rank yields the
solution.
Below are my literate source code with some description. For the
details of Binomial heap, please refer to Okasaki's ``Purely
Functional data structures''[2].
-- Definition
-- Since Fibonacci Heap can be achieved by applying lazy strategy
-- to Binomial heap. We use the same definition of tree as the
-- Binomial heap. That each tree contains:
-- a rank (size of the tree)
-- the root value (the element)
-- and the children (all sub trees)
data BiTree a = Node { rank :: Int
, root :: a
, children :: [BiTree a]} deriving (Eq, Show)
-- Different with Binomial heap, Fibonacci heap is consist of
-- unordered binomial trees. Thus in order to access the
-- minimum value in O(1) time, we keep the record of the tree
-- which holds the minimum value out off the other children trees.
-- We also record the size of the heap, which is the sum of all ranks
-- of children and minimum tree.
data FibHeap a = E | FH { size :: Int
, minTree :: BiTree a
, trees :: [BiTree a]} deriving (Eq, Show)
-- Auxiliary functions
-- Singleton creates a leaf node and put it as the only tree in the
heap
singleton :: a -> FibHeap a
singleton x = FH 1 (Node 1 x []) []
-- Link 2 trees with SAME rank R to a new tree of rank R+1, we re-use
the code
-- for Binomial heaps
link :: (Ord a) => BiTree a -> BiTree a -> BiTree a
link t1@(Node r x c1) t2@(Node _ y c2)
| x

Hi, In CLRS, there are algorithms about DECREASE-KEY and DELETE-NODE. However, in the Functional approach, I didn't find corresponding solution. One approach may just mark the node as `deleted' and when pops the top element from the heap, we repeat it until find a unmarked node. -- LIU https://sites.google.com/site/algoxy/home

Hi, Sorry for there is a bug in my previous post. The example consolidate function for number should be like this: consolidate xs = foldl meld [] xs where meld [] x = [x] meld (x':xs) x | x == x' = meld xs (x+x') | x < x' = x:x':xs | otherwise = x': meld xs x The bug happens in my previous mail like below. --------before fixing--------
consolidate [2, 1, 1, 32, 4, 8, 1, 1, 2, 4] [16,4,32,4]
--------after fixing----------
consolidate [2, 1, 1, 32, 4, 8, 1, 1, 2, 4] [8, 16, 32]
Therefore, the consolidate function for unordered binomial trees should be modified as the following respectively. consolidate :: (Ord a) => [BiTree a] -> [BiTree a] consolidate ts = foldl meld [] ts where meld [] t = [t] meld (t':ts) t | rank t == rank t' = meld ts (link t t') | rank t < rank t' = t:t':ts | otherwise = t' : meld ts t I am sorry for this mistake. The updated source code can be found from here: https://sites.google.com/site/algoxy/otherheaps/otherheaps.zip Happy new year. -- Larry, LIU
participants (1)
-
larry.liuxinyu