【发布时间】:2011-10-10 19:32:18
【问题描述】:
Haskell 的网站介绍了一个非常吸引人的 5 行代码 quicksort function,如下所示。
quicksort [] = []
quicksort (p:xs) = (quicksort lesser) ++ [p] ++ (quicksort greater)
where
lesser = filter (< p) xs
greater = filter (>= p) xs
它们还包括一个“C 语言中的真正快速排序”。
// To sort array a[] of size n: qsort(a,0,n-1)
void qsort(int a[], int lo, int hi)
{
int h, l, p, t;
if (lo < hi) {
l = lo;
h = hi;
p = a[hi];
do {
while ((l < h) && (a[l] <= p))
l = l+1;
while ((h > l) && (a[h] >= p))
h = h-1;
if (l < h) {
t = a[l];
a[l] = a[h];
a[h] = t;
}
} while (l < h);
a[hi] = a[l];
a[l] = p;
qsort( a, lo, l-1 );
qsort( a, l+1, hi );
}
}
C 版本下方的链接指向一个页面,该页面声明“简介中引用的快速排序不是“真正的”快速排序,并且不能像 c 代码那样针对更长的列表进行缩放。'
为什么上面的 Haskell 函数不是真正的快速排序?它如何无法扩展更长的列表?
【问题讨论】:
-
您应该添加指向您正在谈论的确切页面的链接。
-
它不是就地的,所以很慢?实际上是个好问题!
-
@FUZxxl:Haskell 列表是不可变的,因此在使用默认数据类型时不会进行任何操作。至于它的速度 - 它不一定会更慢; GHC 是一项令人印象深刻的编译器技术,使用不可变数据结构的 haskell 解决方案通常可以与其他语言中的其他可变数据结构保持同步。
-
真的不是qsort吗?请记住,qsort 有
O(N^2)运行时。 -
需要注意的是,上面的例子是Haskell的介绍性例子,快速排序对于列表排序是一个非常糟糕的选择。早在 2002 年,Data.List 中的排序就更改为合并排序:hackage.haskell.org/packages/archive/base/3.0.3.1/doc/html/src/…,您还可以在此处看到之前的快速排序实现。当前的实现是 2009 年的合并排序:hackage.haskell.org/packages/archive/base/4.4.0.0/doc/html/src/…。