Answers:
一般而言,有排序算法,例如插入排序,冒泡排序和选择排序,通常只应在特殊情况下使用;快速排序,这是最坏的情况但通常是具有良好的常数和属性,可以用作通用排序过程;的算法,如合并排序和堆排序,这也是很好的通用排序算法; 以及或用于整数列表(例如基数,存储桶和计数排序线性排序算法,这可能取决于列表中整数的性质。O (n 2)O (n log n )O (n log n )O (n )
如果列表中的元素使得您所了解的只是它们之间的总顺序关系,则最佳排序算法将具有复杂度。这是一个很酷的结果,您应该可以轻松地在线找到详细信息。线性排序算法利用有关待排序元素结构的更多信息,而不仅仅是元素之间的总顺序关系。
更一般而言,排序算法的最优性直接取决于您可以对要进行排序的列表的类型做出的假设(以及运行该算法的机器模型,这可能会使排序不佳)算法是最佳选择;请考虑在带有磁带的机器上进行气泡排序存储)。您的假设越强,算法可以消除的角落越多。在关于如何有效地确定列表的“排序性”的非常微弱的假设下,最佳的最坏情况下的复杂度甚至可以是。
这个答案只涉及复杂性。算法实现的实际运行时间将取决于很多因素,这些因素很难在一个答案中解决。
对于此类问题,答案通常是“取决于”。它取决于(a)整数的大小,(b)输入数组是否包含随机顺序或近乎排序的整数,(c)是否需要排序算法稳定,以及其他因素,(d)整个数字列表是否适合内存(内存排序还是外部排序),以及(e)在其上运行的计算机。
在实践中,如果需要内存中的排序,则语言标准库中的排序算法可能会很好(非常接近于最佳)。因此,在实践中,只需使用标准库提供的任何排序功能,并测量运行时间。仅当您发现(i)排序是整个运行时间的很大一部分,并且(ii)运行时间是不可接受的时,才应该理会排序算法。如果这两个条件确实成立,那么您可以查看特定领域的特定方面并尝试使用其他快速排序算法。
但实际上,在实践中,排序算法很少是主要的性能瓶颈。
此外,回答第二个问题
从理论上讲,是否有更快的速度?
那么,排序的最低复杂度是多少?
对于通用分类,基于比较的分类问题复杂度为Ω(n log n)。有一些算法可以在O(n)中执行排序,但是它们都依赖于对输入的假设,而不是通用的排序算法。
基本上,复杂度是由对数组进行排序所需的最少比较次数给出的(log n表示在比较数组的每个元素时构建的二进制决策树的最大高度)。
您可以在此处找到排序复杂度下限的形式证明:
就我遇到的最坏情况而言,最快的整数排序算法是Andersson等人的算法。它的最坏情况为,当然比O (n log log n )要快。
在撰写本文时,我通读了其他两个答案,但我认为没有一个答案能适当回答您的问题。其他答案考虑了关于随机分布和空间复杂性的无关紧要的想法,这可能超出了高中学习的范围。所以这是我的看法。
给定一个具有n个整数元素的数组,您需要在元素之间进行精确的(n − 1 )比较,以检查A是否已排序(仅从数组的开头开始,并针对最后一个元素检查下一个元素)。实际上,(n − 1 )个比较是任何排序算法的最佳案例运行时间。换句话说,任何排序算法的运行时间下限都是Ω (n )。如果您记得基数排序或存储桶排序,您会注意到它们的运行时间为O (n。由于所有排序算法都受 Ω (n )约束,因此我认为基数排序和存储桶排序都是对整数数组进行排序的最快算法。
此外,如果您不熟悉或O (n ):两种表示法都表示该算法大约需要完成n个操作(可以是2 n或3 n - 5,但不能是1或n 2个操作) 。
由于您没有提到对硬件的任何限制,并且考虑到您正在寻找“最快的”,因此我想您应该根据可用的硬件和输入的种类选择一种并行排序算法。
从理论上说quick_sort
是O(n log n)
。对于p
处理器,理想情况下应该归结为O(n/p log n)
如果我们并行运行它。
引用维基百科:时间复杂度...
最佳并行排序为O(log n)
实际上,O(log n)
由于可伸缩性问题,对于庞大的输入大小,将无法实现。
这是并行合并排序的伪代码。的实现merge()
可以与常规合并排序中的相同:
// Sort elements lo through hi (exclusive) of array A.
algorithm mergesort(A, lo, hi) is
if lo+1 < hi then // Two or more elements.
mid = ⌊(lo + hi) / 2⌋
fork mergesort(A, lo, mid)
mergesort(A, mid, hi)
join
merge(A, lo, mid, hi)
另请参阅: