在Haskell中有没有一种简单的方法来实现快速优先级队列?

在Haskell中有没有一种简单的方法来实现快速优先级队列?,haskell,data-structures,functional-programming,priority-queue,finger-tree,Haskell,Data Structures,Functional Programming,Priority Queue,Finger Tree,我在谷歌上搜索了一下,找到了一篇关于手指树的论文,它可以用来实现具有适当渐近复杂性的优先级队列,但它们相当复杂,但仍然是我能找到的最简单的东西 是否有一个简单的数据结构允许在Haskell中实现快速优先级队列?简单地思考,就像你可以向新手程序员解释它一样。声明基于Okasaki的左倾堆 从文档中: 如果需要简单的最小或最大堆(始终将最小/最大元素保留在堆的头部),请选择MinHeap或MaxHeap 如果您希望手动注释具有优先级的值,例如。G带有Int的IO()操作使用MinPrioHeap或M

我在谷歌上搜索了一下,找到了一篇关于手指树的论文,它可以用来实现具有适当渐近复杂性的优先级队列,但它们相当复杂,但仍然是我能找到的最简单的东西

是否有一个简单的数据结构允许在Haskell中实现快速优先级队列?简单地思考,就像你可以向新手程序员解释它一样。

声明基于Okasaki的左倾堆

从文档中:

如果需要简单的最小或最大堆(始终将最小/最大元素保留在堆的头部),请选择MinHeap或MaxHeap

如果您希望手动注释具有优先级的值,例如。G带有Int的IO()操作使用MinPrioHeap或MaxPrioHeap。它们管理(prio,val)元组,以便只有优先级(而不是值)影响元素的顺序

data Heap a = Empty | Heap a [(Heap a)]
    deriving Show

findMin :: Heap a -> a
findMin (Heap h _) = h

merge :: Ord a => Heap a -> Heap a -> Heap a
merge Empty h = h
merge h Empty = h
merge h1@(Heap x hs1) h2@(Heap y hs2)
    | x < y     = Heap x (h2:hs1)
    | otherwise = Heap y (h1:hs2)

mergePairs :: Ord a => [Heap a] -> Heap a
mergePairs []           = Empty
mergePairs [h]          = h
mergePairs (h1:h2:hs)   = merge (merge h1 h2) (mergePairs hs)

insert :: Ord a => a -> Heap a -> Heap a
insert x = merge (Heap x [])

deleteMin :: Ord a => Heap a -> Heap a
deleteMin (Heap x hs) = mergePairs hs
如果您仍然需要一些不同的东西,可以通过实现HeapItem实例来定义heap元素的自定义顺序,并让维护人员知道缺少了什么


我知道在Haskell中实现最简单的堆是

它支持在固定时间(摊销)和对数时间内插入和合并以删除元素

data Heap a = Empty | Heap a [(Heap a)]
    deriving Show

findMin :: Heap a -> a
findMin (Heap h _) = h

merge :: Ord a => Heap a -> Heap a -> Heap a
merge Empty h = h
merge h Empty = h
merge h1@(Heap x hs1) h2@(Heap y hs2)
    | x < y     = Heap x (h2:hs1)
    | otherwise = Heap y (h1:hs2)

mergePairs :: Ord a => [Heap a] -> Heap a
mergePairs []           = Empty
mergePairs [h]          = h
mergePairs (h1:h2:hs)   = merge (merge h1 h2) (mergePairs hs)

insert :: Ord a => a -> Heap a -> Heap a
insert x = merge (Heap x [])

deleteMin :: Ord a => Heap a -> Heap a
deleteMin (Heap x hs) = mergePairs hs
数据堆a=空|堆a[(堆a)]
衍生节目
findMin::堆a->a
findMin(堆h u)=h
合并::Ord a=>堆a->堆a->堆a
合并空h=h
合并h空=h
合并h1@(堆x hs1)h2@(堆y hs2)
|x[堆a]->堆a
mergePairs[]=空
合并对[h]=h
合并对(h1:h2:hs)=合并(合并h1 h2)(合并对hs)
插入::Ord a=>a->a堆->a堆
插入x=合并(堆x[])
deleteMin::Ord a=>堆a->堆a
deleteMin(堆x hs)=合并对hs

是。购买Chris Okasaki的纯功能数据结构的副本。他描述的左派堆很简单。他还描述了各种其他优先级队列实现,一直到Brodal Okasaki队列(具有O(1)合并的优先级队列)。手指树对于优先级队列来说有点傻,除非你想轻松访问最大值和最小值。有人能解释一下为什么这会被否决吗?我以为你应该写一篇评论来解释为什么你否决了某件事,如果一篇评论没有给出这个理由的话。包含关于Haskell PQUE实现的广泛讨论。@bitemyapp,如果您将鼠标悬停在“向下投票”按钮上,它会告诉您。我个人对此投了反对票,因为尽管OP声称相反,但显然他们几乎没有努力寻找答案。谷歌搜索Haskell priority queue的前两页搜索结果显示了大量信息。我没有看到左派的堆,但我确实看到了二项式堆,它们也不太复杂。包含一篇我在Haskell中写的关于各种高效优先级队列实现的文章。谢谢!这正是我想要的。我相信这些摊销界限只有在以单线程方式使用堆时才成立。