您的位置:首页 > 产品设计 > UI/UE

优先队列(Priority Queue)变种和加强

2014-01-05 17:49 148 查看
在《Handbook of Data Structures and Applications》一书中,介绍和讨论了一系列针对不同需求的设计精妙的Priority Queue和参考文献。这一系列的优先队列设计,都是在基于最原始的queue和priority queue的基础上,针对新需求,提出的变种和增强版本数据结构。非常具有启发性。

下面包含这些Priority Queue之间的关系:

Queue

队列 (Queue) 是一个基本的数据结构。支持先进先出 (FIFO: First In First Out) 的线形表。主要支持下面两个操作: 

  EnQueue:往队列尾端插入一个元素

  DeQueue:从队列首端弹出一个元素

 

--------------------------------------------------

如果队列中的元素有不同的优先级, 而每次出队操作是返回优先级最高的元素,而不是简单的队首元素。怎么支持这个需求呢?

 Priority Queue

优先队列(Priority Queue)是为了满足上述需求设计的数据结构。 跟队列类似地,它支持下列三个基本操作:

  Insert: 往优先队列中插入一个元素。 类似于EnQueue

  Delete:从优先队列中删除优先级最高的元素。类似于DeQueue

  Min: 返回优先队列中优先级最高的元素

堆(Heap)是经典的优先队列。

-------------------------------------------------- 

如何支持合并操作,从而能快速实现两个优先队列的合并呢?

 Meldable Priority Queue

  Leftist Tree是一个能在O(log n) 时间里实现meld操作的数据结构。有两种Leftiest Tree: Height-based Leftist Tree 和 Weight-based Leftist Tree。 HBLT和WBLT都在支持基本的Insert, Delete, Min操作之外,还支持Meld操作。

  HBLT还可以在O(logN)时间内实现对队列中任意元素的删除操作。但,WBLT不能保证在O(log N)时间内。

  一般,优先队列并不需要实现队列中任意元素的删除操作。这个操作在Double-Ended Priority Queue构造中有用。

 

  在Leftist Tree中,不管是HBLT还是WBLT,都需要通过存储额外信息用于指导树的调整,从而保持一定意义上的“平衡”。

  

  Skew Heap是一种不需要额外信息的可归并优先队列。

 --------------------------------------------------

如何支持调整队列中的某个元素的优先级?

 

Fibonacci Heap

  Binomial Heap是一个非常优美的可归并优先队列。 而Fibonacci Heap是在Binomial Heap基础上改进得到的可以支持DecreaseKey操作(调整队列中某个元素的优先级)的可归并优先队列。

  类似于Leftist Tree和Skew Heap的关系, 对应于Fibonacci Heap, 有Pairing Heap。

 

--------------------------------------------------

如何设计一个能够支持双端操作的优先队列?

 

Double-Ended Priority Queue

  一个双端优先队列需要支持下列5个基本操作: 

  Insert: 插入一个元素

  DeleteMin: 删除优先级最小的元素

  DeleteMax: 删除优先级最大的元素

  Min: 返回优先级最小的元素

  Max:返回优先级最大的元素

 

   最朴素的实现方法,当然是维护两个优先队列。 一个按优先级从大到小,另一个按优先级从小到大。但,我们需要利用指针把两个优先队列中的相同的元素关联起来。例如,进行DeleteMin操作的时候,很容易地我们可以删除MinPriorityQueue的最小元素,但同时我们也需要删除MaxPriorityQueue中对应的这个最小元素。这就需要PriorityQueue能够支持删除队列中的任意元素而不仅仅是优先级最大(或最小)元素。

  是否可以不保存两份数据呢?怎么设计呢?

 

  如果考虑把数据分成两部分:MinPart (比较小的部分) 和 MaxPart (比较大的部分),Min/DeleteMin和Max/DeleteMax就分别对应于MinPart和MaxPart。在操作实现中,对数据结构的调整主要得保证:Insert/DeleteMin/DeleteMax的操作能保持|MinPart| ~= |MaxPart|。 这两部分大小相当,从而能保证整体时间复杂度为O(logN),不至于退化。

  要使得MinPart,MaxPart大小相当,操作过程中肯定涉及元素在MinPart和MaxPart之间流动。什么情况下会发生这些变化呢?

  

  有很多精妙的设计可以保证只需要保存一份数据: Symmetric Min-Max Heap, Interval Heap, Twim Heaps, Min-Max pair heap, Diamond Deques, Min-Max Heaps, Deaps。 这些数据结构中,有相当部分本质上都是一致的。

 

--------------------------------------------------

如何设计一个能够支持双端操作的可归并优先队列?

 

Meldable Double-Ended Priority Queue

  一般方法: Dual Priority Queue + Meldable Priority Queue

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息