在书http://www.scala-lang.org/docu/files/ScalaByExample.pdf的第2章中,M。Odersky写了以下快速排序的实施
def sort(xs: Array[Int]): Array[Int] = {
if (xs.length <= 1) xs
else {
val pivot = xs(xs.length / 2)
Array.concat(
sort(xs filter (pivot >)),
xs filter (pivot ==),
sort(xs filter (pivot <)))
}
}
并说“命令式和功能性实现都具有相同的渐近性 复杂性 - 平均情况下的O(N log(N))“ 但它看起来不是,因为我们应用过滤谓词两次来分区数组。在经典命令式版本中,我们使用一个循环来表示数组。那么功能实现的运行时间是否为O(N log(N))?
答案 0 :(得分:4)
filter
本身具有O(n)和O(3n)= O(n),因为3是常数因子。无论n多大,过滤器只会被调用3次。
编辑:过滤器被调用3次
答案 1 :(得分:2)
Quicksort和许多其他分而治之的算法最多可以在O(n)
次工作时工作,对数据的传递不超过O(log(n))
次。在每一步,我们将数据大致分成两半,这意味着我们确实只有log2(n)
通过数据(一个没有被分割,一个被分成大约一半等)。
然后你只需要检查每次传递数据的时间不会超过O(n)
。过滤器是O(n)
,我们过滤三次;加concat
为O(n)
,我们只执行一次。因此,我们4*O(n)
工作,O(n)
。
这不是最有效的算法,因为所有传递都在相同的数据上,但它是正确的顺序。