这是我在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实现http://algs4.cs.princeton.edu/22mergesort/Merge.java.html慢得多(大约10倍),并且使用了大量内存。是否有更快的合并排序实现是函数式的?显然,可以逐行移植Java版本,但这不是我要找的。
更新:我已将Stream
更改为List
,将#::
更改为::
,排序例程变得更快,只比Java版本慢三到四倍。但我不明白为什么不会因堆栈溢出而崩溃?merge
不是尾递归,所有参数都是严格求值的...这怎么可能?
Iterator.continually(Random.nextInt).take(N).toList
生成一个任意大的未排序列表。 - Aaron Novstrup