我正在用C ++编写一个应用程序,其中对优先级队列进行O(1)Dequeue操作至关重要,而Enqueue的复杂性并不是那么重要(除非它变成n ^ 2或2 ^ n当然)。
起初我使用了一个链表。这对Dequeue(O(1))来说非常好,并且它具有良好的入队复杂性。唯一的问题是,整理它。使用Insertion Sort,O(n)复杂度并不符合我的需求。但排序链表很麻烦。这是懒散的。
矢量并不好。 Dequeue将是O(n)将所有元素移回一个地方。入队仍然是O(n)但速度要快得多。
你能建议更高效的方法吗?感谢。
答案 0 :(得分:14)
反向排序的vector
包含O(1)pop_back
和O( n )插入。
答案 1 :(得分:10)
您可以将队列存储为已排序的链接列表。删除前面的元素是O(1)
,并且在正确的位置插入元素是O(n)
。
但是对链表进行排序是一件痛苦的事。这是懒散的。
每次插入后,您不必执行完整排序。您所要做的就是遍历(已经排序的)列表以找到新元素的正确位置,并将其插入其中。遍历为O(n)
,插入为O(1)
。
答案 2 :(得分:1)
如果您愿意从文献中实施,那么我会为您提供更好的解决方案。
删除:O(1)
删除分钟:O(1)
Find-min :O(1)
插入:O(log n)
如果允许MELD 采用线性时间,则可以通过使用Dietz和Raman的手指搜索树来支持 DELETE-MIN 在最坏情况下的恒定时间{{ 1}}。 通过使用其数据结构 MAKEQUEUE , FINDMIN , DELETEMIN ,在最坏的情况下可以支持 DELETE O(1 ), INSERT 在最坏情况下时间O(log n)和 MELD 在最坏情况下时间O(n)。
虽然这使用RAM model of computation:
我们的数据结构使用具有单位成本测量和对数字大小的随机访问机器(RAM)模型;
最近,Pointer-Machine计算模型中的解决方案已被赋予[3]
。这有O(1)get-min,extract-min,get-max,extract-max和O(log n)插入。
答案 3 :(得分:0)
Boost现在包括Boost.Heap,这是一个堆数据结构库,也支持优先级队列操作。 This page有一个表格,列出了每个提供的数据结构的核心操作的复杂性。 Fibonacci堆特征:O(1)推送,O(log(N))pop,O(1)增加,以及(如果需要)O(log(N))减少。
答案 4 :(得分:0)
可以将平衡二叉搜索树与链表结合起来。树的每个元素都有指向其子元素的链接,也链接到下一个元素。然后你可以:
O(lg n)插入,删除,搜索; O(1) - 提取min + max
如果你不介意使用随机结构,另一种可能性就是使用skiplist。比你还要:
O(lg n)插入,删除,搜索; O(1) - 提取min + max