Scala - PriorityQueue 的订购失败

Posted

技术标签:

【中文标题】Scala - PriorityQueue 的订购失败【英文标题】:Scala - Ordering fails for PriorityQueue 【发布时间】:2020-02-08 06:46:35 【问题描述】:

我正在尝试在 Scala 中创建一个简单的优先级队列:

val priorities: mutable.PriorityQueue[Priority] = mutable.PriorityQueue(
 Priority(2, 302),
 Priority(3, 300),
 Priority(5, 400),
 Priority(4, 309),
 Priority(1, 301)
)(Ordering.by[Priority, Int](_.priority).reverse)

case class Priority(priority: Int, value: Int)

当我这样做时priorities.foreach(p => println(p.priority, p.value))

我期望的输出是:

(1,301)
(2,302)
(3,300)
(4,309)
(5,400)

但相反,我得到:

(1,301)
(2,302)
(5,400)
(4,309)
(3,300)

如您所见,排序存在一些问题。我能否了解一下我哪里出了问题以及我应该怎么做才能获得所需的输出?

【问题讨论】:

来自 scaladoc:只有 dequeue 和 dequeueAll 方法会按优先级顺序返回元素。包括 drop、iterator 和 toString 在内的标准收集方法将以最方便的顺序删除或遍历堆。因此,打印 PriorityQueue 不会显示元素的优先级顺序,尽管最高优先级的元素将首先打印。要按顺序打印元素,必须复制 PriorityQueue(例如使用克隆),然后将它们出列: 【参考方案1】:

foreach 方法处理PriorityQueue 的所有元素,但不一定按排序顺序。如果您删除元素,您可以看到排序正在运行:

while (priorities.nonEmpty) println(priorities.dequeue())

Priority(1,301)
Priority(2,302)
Priority(3,300)
Priority(4,309)
Priority(5,400)

该实现将第一个元素保留为最高优先级元素,但其余元素未排序。 dequeue 会将新的最高优先级元素放在前面。

似乎没有一种非破坏性的方式可以按顺序显示整个PriorityQueue

【讨论】:

哦,感谢您指出简单地遍历 PriorityQueue 不会给我命令。我只是想将其用作 Min_heap。非常感谢。

以上是关于Scala - PriorityQueue 的订购失败的主要内容,如果未能解决你的问题,请参考以下文章

Scala :: PriorityQueue => 更新特定项目的优先级

使用带有 PriorityQueue (Scala) 的隐式排序时遇到问题

Scala PriorityQueue 冲突解决?

Scala 问题对 Stack[A] 使用 PriorityQueue 非默认排序

scala.collection.mutable.PriorityQueue:与案例类的 2 个或更多属性进行比较

按非案例类的字段排序 PriorityQueue