这是我在 Scala 中的合并排序实现:
object FuncSort {
def merge(l: Stream[Int], r: Stream[Int]) : Stream[Int] = {
(l, r) match {
case (h #:: t, Empty) => l
case (Empty, h #:: t) => r
case (x #:: xs, y #:: ys) => if(x < y ) x #:: merge(xs, r) else y #:: merge(l, ys)
}
}
def sort(xs: Stream[Int]) : Stream[Int] = {
if(xs.length == 1) xs
else {
val m = xs.length / 2
val (l, r) = xs.splitAt(m)
merge(sort(l), sort(r))
}
}
}
它工作正常,似乎渐近它也很好,但它比这里的 Java 实现慢(大约 10 倍)http://algs4.cs.princeton.edu/22mergesort/Merge.java.html并使用很多内存。是否有更快的合并排序实现功能?显然,可以逐行移植 Java 版本,但这不是我想要的。
UPD:我更改Stream
了 toList
和#::
to ::
,排序例程变得更快,仅比 Java 版本慢三到四倍。但我不明白为什么它不会因堆栈溢出而崩溃?merge
不是尾递归的,所有参数都经过严格评估……这怎么可能?