【发布时间】:2017-01-26 19:51:25
【问题描述】:
我正在尝试在 Scala 中编写一个尾递归快速排序,它通过建立一个延续来工作,而不使用蹦床。到目前为止,我有以下内容:
object QuickSort {
def sort[A: Ordering](toSort: Seq[A]): Seq[A] = {
val ordering = implicitly[Ordering[A]]
import ordering._
@scala.annotation.tailrec
def step(list: Seq[A], conts: List[Seq[A] => Seq[A]]): Seq[A] = list match {
case s if s.length <= 1 => conts.foldLeft(s) { case (acc, next) => next(acc) }
case Seq(h, tail @ _*) => {
val (less, greater) = tail.partition(_ < h)
step(less, { sortedLess: Seq[A] =>
/*
Can't use
step(greater, sortedGreater => (sortedLess :+ h) ++ sortedGreater)
and keep the tailrec annotation
*/
(sortedLess :+ h) ++ sort(greater)
} +: conts)
}
}
step(toSort, Nil)
}
}
在我的计算机上,上述实现适用于至少 4000000 个元素的随机序列,但我对此表示怀疑。具体来说,我想知道:
- 它是堆栈安全的吗?我们可以通过查看代码来判断吗?它使用
@tailrec编译,但对sort(greater)的调用似乎有点可疑。 - 如果 (1) 的答案是“否”,是否可以在 Scala 中以 CPS 样式编写尾递归快速排序,即不使用蹦床?怎么样?
为了清楚起见,我查看了this related question,它讨论了如何使用蹦床(我知道如何使用)或您自己的显式堆栈来实现尾递归快速排序,但我特别想知道是否和如何以不同的方式完成。
【问题讨论】:
标签: scala sorting recursion tail-recursion continuations