不同语言如何在标准库中实现排序?

时间:2013-04-30 20:23:24

标签: c sorting programming-languages standard-library

从我的(简要)读到,Java和Python看起来都像是在他们的标准库中使用了timsort,而C的stdlib中的排序方法叫做qsort,因为它曾经是快速排序。

现在标准库中的典型语言实现了什么算法,为什么选择该算法?另外,C是否偏离了快速排序?

我知道这个问题缺乏“我面临的实际问题”,并且可能看起来对某些人来说是开放性的,但是知道如何/为什么某些算法被选为标准似乎非常有用但相对没有被捕获。我也觉得,如果一个深入的答案解决特定于语言(数据类型?)和机器特定(缓存命中?)的问题,将提供更多洞察不同语言和算法的工作方式,而不是单一的解释。

4 个答案:

答案 0 :(得分:1)

C没有具体说明qsort使用的算法。

当前glibc(2.17)qsort分配内存(如果需要的内存非常小,则使用mallocalloca)并使用合并排序算法。如果内存要求过高或malloc失败,则使用快速排序算法。

答案 1 :(得分:1)

musl中,我们使用Smooth Sort。从概念上讲,它是堆排序的变体(同样是就地和O(n log n)时间),但它具有良好的属性,即最坏情况的性能接近O(n)已经排序或接近排序的输入。我不相信它是最好的选择,但是使用O(n log n)最坏情况的就地算法似乎很难做得更好。

作为一个鲜为人知的Dijkstra发明也让它变得很酷。 : - )

答案 2 :(得分:0)

我的机器的C库提供qsortheapsortmergesort,在man page中说:

  

qsort() qsort_r() 函数是C.A.R的实现。 Hoare的“快速排序”算法,分区交换排序的一种变体;尤其见D.E.        Knuth的算法Q 。 Quicksort的平均时间为 O(n lg n)。此实现使用中值选择来避免其 O(n 2 最坏情况行为。

     

heapsort() 函数是J.W.J.的实现。 William的“heapsort”算法,一种选择排序的变体;尤其见D.E. Knuth的算法H 。        Heapsort采用 O(n lg n)最坏情况时间。它比 qsort() 的唯一优势是它几乎不使用额外的内存;虽然 qsort() 不分配内存,但确实如此        使用递归实现。

     

函数 mergesort() 需要额外的内存 nel * width 字节;只有当空间不是很重要时才应该使用它。 mergesort() 功能针对具有预先存在订单的数据进行了优化;最坏的情况是 O(n lg n);最好的情况是 O(n)

     

通常情况下, qsort() mergesort() 更快,比 heapsort() 更快。内存可用性和数据中预先存在的顺序可能会导致这种情况不真实。

如果您想查看实施的具体细节,可以查看大量的开源C库。

至于'为什么系统X选择算法Y',这是一个非常难以回答的问题 - 如果你没有足够的幸运在文档中找到理由,你必须直接向设计师询问。

答案 3 :(得分:0)

我在C11标准中对qsort()进行了快速扫描,但我找不到有关如何实施qsort()的任何参考资料 以及算法的预期时间/空间复杂度。所有它必须说的是关于比较器的某些条件 功能。

这意味着实现可以选择适合qsort()的任何基于比较器的算法。例如,实现可以选择使用诸如 bubble sort 之类的天真算法来实现qsort(),这不如真正的 quick sort 。底线是决定实际算法的实现。