PriorityQueue
实现了 Queue
接口,但是它是否像 Queue
一样是一个 FIFO 数据结构呢?
PriorityQueue
实现了 Queue
接口,但是它是否像 Queue
一样是一个 FIFO 数据结构呢?
因此,PriorityQueue是一种例外,只有当比较器按照这个顺序排序时,它才成为FIFO队列。队列通常按照FIFO(先进先出)的方式排序元素,但并非一定如此。优先级队列是其中之一,它根据提供的比较器或元素的自然排序对元素进行排序。
PriorityQueue(优先队列)不关心先进先出(FIFO)/后进先出(LIFO)。 它处理优先级。 如果有多个具有相同优先级的对象,则不能依赖于任何FIFO LIFO行为。
这取决于您使用的比较器。
例如,假设您正在使用优先队列来管理事件队列,这些事件计划在未来的墙钟时间或概念批处理模式中调用。最高优先级基本上是最早的时间,并且您将使用类似以下的比较器:
first.time < second.time
如果比较器只是比较两个事件的时间,它们将以未定义的顺序出队,并且很可能不是先进先出。
然而,您可以维护Enqueue操作的计数;将其存储在优先级队列元素中;并使您的比较使用队列操作作为tie-breaker。例如:
first.time < second.time || ( first.time == second.time && first.count < second.count )
然后你将获得FIFO行为。如果计数器是32位的,您可以在1000小时内进行1000次入队/秒,然后它会绕回。如果计数器是64位的,则可以在500多年内进行十亿次入队/秒,然后才会绕回。即使计数器绕回,您也可以简单地重新编号所有现有的优先级队列元素:将它们全部出队到一个向量中;对向量进行排序;用其向量元素号覆盖每个向量元素的计数器;并重新插入到优先级队列中。该向量大小成为您的新计数器。
PriorityQueue不遵循FIFO原则,这可能是您问题的原因。队列通常按照FIFO(先进先出)方式排序元素,但并非必须如此。其中的例外是优先级队列,它根据提供的比较器或元素的自然顺序来排序元素。