我正在尝试使用Scala编写一个耐心排序的简单实现 我已经正确设法创造了最初的桩;但是,我使用优先级队列来简化输出列表的生成让我很头疼。
看来我的订单执行错误或被忽略:
def PileOrdering = new Ordering[Stack[A]] {
def compare(a : Stack[A], b : Stack[A]) = a.head.compare(b.head)
}
// Use a priority queue, ordering on stack heads (smallest stack elems)
val pq = new PriorityQueue[Stack[A]]()(PileOrdering)
// piles is a List[Stack[A]]
pq ++= piles
// Extract an ordered list of elements
val returnVal = (0 until count) map (_ => {
val smallestList = pq.dequeue
val smallestVal = smallestList.pop
if (smallestList.length > 0){
pq.enqueue(smallestList)
}
smallestVal
})
PriorityQueue似乎按(我想象默认的堆栈顺序)堆栈大小排序,而不是我的订购。
有什么事情突然显然是错误的吗? 任何帮助都会受到很大的欢迎 谢谢,
编辑:我在原始问题中没有说清楚:我正在使用Scala 2.8.1。
Edit2:我期望returnVal包含从最小到最大的元素排序,通过从所有堆栈的头部获取最小元素。丹尼尔指出,我的订购将从最大到最小的顺序排列我的堆栈(堆栈本身已经正确排序,最小元素在顶部),这似乎是问题。
答案 0 :(得分:1)
根据排序,您是否对优先级队列中的第一个元素是最大值的元素感到困惑?代码似乎期望第一个元素是具有最小值的元素。
答案 1 :(得分:0)
稍微难以回答正在发生的事情,因为您没有将整个程序包含在输入和输出中。我的猜测是,这是由于2.8.1中PriorityQueue
的旧实现。以下程序使用自定义排序,并使用堆栈列表填充优先级队列:
import collection._
import collection.mutable.PriorityQueue
import collection.mutable.Stack
class Test[A](piles: Traversable[Stack[A]])(implicit ord: Ordering[A]) {
def PileOrdering = new Ordering[Stack[A]] {
def compare(a : Stack[A], b : Stack[A]) = ord.compare(a.head, b.head)
}
// Use a priority queue, ordering on stack heads (smallest stack elems)
val pq = new PriorityQueue[Stack[A]]()(PileOrdering)
// piles is a List[Stack[A]]
pq ++= piles
}
object Main {
def main(args: Array[String]) {
val t = new Test(Seq(Stack(1, 2, 3), Stack(15, 8), Stack(3, 4, 9, 0, -1), Stack(45, 1, 2, 3, 4)))
while (t.pq.nonEmpty) {
println(t.pq.dequeue)
}
}
}
程序输出:
Stack(45, 1, 2, 3, 4)
Stack(15, 8)
Stack(3, 4, 9, 0, -1)
Stack(1, 2, 3)
使用Scala主干,看起来是正确的。我应该指出PriorityQueue
经历了一些更改,由于二进制兼容性原因,这些更改未包含在2.8.1中,但将在2.9中提供:
apply
和update
无法有意义地实现toString
或迭代元素不会产生堆顺序 - 获取它的唯一方法是使用dequeue