【发布时间】:2018-05-14 14:59:57
【问题描述】:
我正在尝试使用“Purely Functional Data Structures” Chris Okasaki 一书在 Haskell 中实现二项式堆。
{- Implemetation of Binomial Heap-}
module BinomialHeap where
{- Definition of a Binomial Tree -}
data BTree a = Node Int a ([BTree a]) deriving Show
{- Definition of a Binomial Heap -}
data BHeap a = Heap [BTree a] deriving Show
empty :: BHeap a
empty = Heap []
{- Linking function tree -}
-- w/ larger root is
-- linked w/ tree w/ lower root -}
link :: Ord a => BTree a -> BTree a -> BTree a
link t1@(Node r x1 c1) t2@(Node _ x2 c2) =
if x1 < x2 then
Node (r+1) x1 (t2:c1)
else
Node (r+1) x2 (t1:c2)
root :: BTree a -> a
root (Node _ x _) = x
{- Gives the rank of the Binomial Tree-}
rank :: BTree a -> Int
rank (Node r _ _ ) = r
{- Insertion in the tree -}
-- Create a new singl. tree
-- Step through the existing trees in increasing order
-- until we find a missing rank
-- link tree of equal ranks
-- atm it's O(log n)
insTree :: Ord a => BTree a -> [BTree a] -> [BTree a]
insTree t [] = [t]
insTree t ts1@(t1':ts1') =
if rank t > rank t1' then
t:ts1
else
insTree (link t t1') ts1'
insert :: Ord a => BHeap a -> a -> BHeap a
insert (Heap ts) x = Heap $ insTree (Node 0 x []) ts
{- Merge of Heaps-}
-- We step through both list of tree in increasing order
-- link tree of equal root
merge :: Ord a => [BTree a] -> [BTree a] -> [BTree a]
merge [] ts = ts
merge ts [] = ts
merge ts1@(t1:ts1') ts2@(t2:ts2') =
if rank t1 < rank t2 then
t1:merge ts1' ts2
else if rank t2 < rank t1 then
t2:merge ts1 ts2'
else
insTree (link t1 t2) (merge ts1' ts2')
sampleHeap :: BHeap Int
sampleHeap = foldl insert empty [1, 2, 3]
问题是插入给了我一个不正确的输出:
Heap [Node 1 1 [Node 0 3 [],Node 0 2 []]]
插入原语可能不正确。冈崎 说:
“要向堆中插入一个新元素,我们首先创建一个新的单例树(等级 0)。然后我们按等级递增的顺序逐步遍历现有的树,直到找到缺失的等级,将具有相同等级的树连接为我们走吧。每个链接对应一个二进制算术进位"
您能帮我找出插入原语中可能存在错误的地方吗? 谢谢。
【问题讨论】:
-
欢迎来到 StackOverflow。请将问题简化为minimal reproducible example,这样我们就不必跳过与问题无关的代码。
-
你说输出“不正确”;你期望得到什么?
标签: haskell