按优先关系选择下一项
普通先进先出队列按加入先后取出元素,优先队列则比较指定的优先键。最小优先队列可返回当前键最小的一项,最大优先队列取最大的一项;在每次取出之间,结构还可以接收新的内容。
接口描述的是可观察行为,而不限定只能用二叉堆。无序数组、有序数组和链接结构也能实现相应操作,只是在插入、寻找极值和移除时分担不同成本。堆是一种常见实现,不是优先队列这个抽象的全部含义。
参考:[1]
相同优先级需要明确次序
只有优先键相同,并不能推定接口一定先返回较早加入的任务。若需要稳定先后,可以把递增序号与优先级一起用于比较,使相同优先级的项按序号决定顺序。
Python的heapq文档给出优先级、序号、任务三项组合的做法。独立序号还避免优先级相等时继续直接比较两个本来没有大小顺序的任务对象。公平策略和稳定次序要由这些规则表达,不能只凭“队列”这个名称推断。
参考:[2]
待办变化后维护结构
等待中的任务可能被取消,或被赋予新的优先级。直接修改堆内键值,可能使原来的父子顺序失效;接口需要重新调整位置,或者采用能够识别旧记录失效的方案。
heapq示例使用字典定位当前条目,把旧条目标记为删除,再加入新的优先级记录;取出时跳过无效项。这种策略也会保留暂未清理的旧记录,因此逻辑待办数量与底层占用需要分别观察,并按实际工作方式控制资源。