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

C 不同语言如何在其标准库中实现排序?,c,sorting,programming-languages,standard-library,C,Sorting,Programming Languages,Standard Library,从我(简要地)读到的内容来看,Java和Python看起来都在其标准库中使用了timsort,而C的stdlib中的排序方法被称为qsort,因为它曾经是quicksort 今天,典型语言在其标准库中实现了什么算法?他们为什么选择该算法?另外,C是否偏离了快速排序 我知道这个问题缺乏一个“我所面临的实际问题”,对某些人来说可能是开放的,但知道某些算法是如何/为什么被选为标准的似乎非常有用,但相对来说还不成熟。我还觉得,如果能深入回答语言特定(数据类型?)和机器特定(缓存命中?)的问题,就可以更深

从我(简要地)读到的内容来看,Java和Python看起来都在其标准库中使用了timsort,而C的stdlib中的排序方法被称为qsort,因为它曾经是quicksort

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


我知道这个问题缺乏一个“我所面临的实际问题”,对某些人来说可能是开放的,但知道某些算法是如何/为什么被选为标准的似乎非常有用,但相对来说还不成熟。我还觉得,如果能深入回答语言特定(数据类型?)和机器特定(缓存命中?)的问题,就可以更深入地了解不同语言和算法的工作原理,而不是uni愿意解释的。

我的机器的C库提供了
qsort
heapsort
,以及
mergesort
,在信中说:

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

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

函数
mergesort()
需要大小为
nel*width
字节的额外内存;只有在空间不够大的情况下才能使用。
mergesort()
函数针对已有订单的数据进行了优化;其最坏情况时间为O(nlgn);它的最佳情况是O(n)

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

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


至于“为什么system X选择了算法Y”,这是一个很难有意义地回答的问题——如果你没有幸运地在文档中找到一个基本原理,你必须直接问设计师。

我在C11标准中快速浏览了一下,但我找不到任何关于如何
qsort()的参考资料
应予以实施 以及算法的预期时间/空间复杂度。它所要说的只是关于比较器的某些条件 功能


这意味着实现可以选择任何适合qsort()的基于比较器的算法。例如,一个实现可以选择使用诸如之类的简单算法来实现qsort(),该算法的效率不如真正的算法。底线是,由实现来决定实际的算法。

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

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

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


Dijkstra的一项鲜为人知的发明也让它有点酷。:-)

我相信OSX的独特之处在于它包含了heapsort和mergesort。我工作的两台机器和我的uni服务器除了qsort和qsort\r之外什么都没有。另外,我知道这个问题很难问,因为它涉及到很多历史,可能是一些政治,肯定是一些对各种制度的深入了解和大量阅读。这类问题如果不是期末考试,我可能会自己回答。但即便如此,仍有很多需要研究。我希望有人在更早的时候对这个答案有热情。是的,这是很有可能的。我的观点主要是,除了文档或直接查看您关心的实现之外,没有太多信息可供参考。是的,我也这么认为。我希望,如果在公开邮件列表中做出了任何决策,或者你有什么发现,有人会记住决策过程并提供见解。我怀疑它在失败案例中仍然使用introsort,而不是简单的快速排序。但我没有检查。我检查过了,就我所理解的代码而言,它是快速排序。另外,当分区很小(<4个元素)时,他们的快速排序实现使用简单的插入排序。Introsort是glibc的快速排序变体,它跟踪连续分区大小的比率,以检测何时可能进入O(n²)最坏情况,并在这种情况下切换到heapsort。我想知道为什么他们对小分区使用插入排序。。。使用排序网络进行叶子排序应该更好。源文件提到了Sedgewick讨论的4个快速排序优化,但似乎没有提到