0 | module SkewBinomialHeap
8 | data Tree a = Node Int a (List a) (List (Tree a))
11 | data SkewBinomialHeap a = SBH (List (Tree a))
13 | rank : Tree a -> Int
14 | rank (Node r x xs c) = r
17 | root (Node r x xs c) = x
19 | link : Ord a => Tree a -> Tree a -> Tree a
20 | link t1@(Node r x1 xs1 c1) t2@(Node _ x2 xs2 c2) =
21 | if x1 <= x2 then Node (r + 1) x1 xs1 (t2 :: c1)
22 | else Node (r + 1) x2 xs2 (t1 :: c2)
24 | skewLink : Ord a => a -> Tree a -> Tree a -> Tree a
26 | let Node r y ys c = link t1 t2
27 | in if x <= y then Node r x (y :: ys) c else Node r y (x :: ys) c
29 | insTree : Ord a => Tree a -> List (Tree a) -> List (Tree a)
31 | insTree t ts@(t' :: ts') =
32 | if rank t < rank t' then t :: ts else insTree (link t t') ts'
34 | mrg : Ord a => List (Tree a) -> List (Tree a) -> List (Tree a)
37 | mrg ts1@(t1 :: ts1') ts2@(t2 :: ts2') = case compare (rank t1) (rank t2) of
38 | LT => t1 :: mrg ts1' ts2
39 | GT => t2 :: mrg ts1 ts2'
40 | EQ => insTree (link t1 t2) (mrg ts1' ts2')
42 | normalize : Ord a => List (Tree a) -> List (Tree a)
44 | normalize (t :: ts) = insTree t ts
46 | removeMinTree : Ord a => List (Tree a) -> (Tree a, List (Tree a))
47 | removeMinTree [] = assert_total $
idris_crash "empty heap"
48 | removeMinTree [t] = (t, [])
49 | removeMinTree (t :: ts) = let (t', ts') = removeMinTree ts in
50 | if root t < root t' then (t, ts) else (t', t :: ts')
52 | nlInsert : a -> List (Tree a) -> SkewBinomialHeap a
53 | nlInsert x ts = SBH (Node 0 x [] [] :: ts)
56 | Heap SkewBinomialHeap where
58 | isEmpty (SBH ts) = isNil ts
60 | insert x (SBH ts@(t1 :: t2 :: ts')) =
61 | if rank t1 == rank t2 then SBH (skewLink x t1 t2 :: ts')
63 | insert x (SBH ts) = nlInsert x ts
65 | merge (SBH ts1) (SBH ts2) = SBH (mrg (normalize ts1) (normalize ts2))
67 | findMin (SBH ts) = root (fst (removeMinTree ts))
69 | deleteMin (SBH ts) = let (Node _ x xs ts1, ts2) = removeMinTree ts
70 | ts' = mrg (reverse ts1) (normalize ts2)
71 | in foldr insert (SBH ts') xs