什么是最快的整数数组排序算法?


55

在高中学习期间,我遇到了许多排序算法。但是,我不知道哪一个最快(对于整数随机数组)。所以我的问题是:

  • 当前已知最快的排序算法是哪一个?
  • 从理论上讲,是否有更快的速度?那么,排序的最低复杂度是多少?

6
“快速”是什么意思?您要测量什么?
拉斐尔

2
“整数随机数组”是什么意思?随机有什么分布?均匀分布?高斯?根据分布情况,可能会比预期运行时间算法更好。Øñ日志ñ
Bakuriu

@gen看一下Radix排序。正确的实现例如对于Int32具有O(n)复杂度。
这个


1
@gen:就渐近而言?然后,这很容易:选择任何算法。请注意,这可能与(平均)实际性能无关。在这方面,可能是值得阅读的。Θ Ñ 登录Ñ ΘΘñ日志ñ
拉斐尔

Answers:


42

一般而言,有排序算法,例如插入排序,冒泡排序和选择排序,通常只应在特殊情况下使用;快速排序,这是最坏的情况但通常是具有良好的常数和属性,可以用作通用排序过程;的算法,如合并排序和堆排序,这也是很好的通用排序算法; 以及或用于整数列表(例如基数,存储桶和计数排序线性排序算法,这可能取决于列表中整数的性质。O n 2O n log n O n log n O n Øñ2Øñ2Øñ日志ñØñ日志ñØñ

如果列表中的元素使得您所了解的只是它们之间的总顺序关系,则最佳排序算法将具有复杂度。这是一个很酷的结果,您应该可以轻松地在线找到详细信息。线性排序算法利用有关待排序元素结构的更多信息,而不仅仅是元素之间的总顺序关系。Ωñ日志ñ

更一般而言,排序算法的最优性直接取决于您可以对要进行排序的列表的类型做出的假设(以及运行该算法的机器模型,这可能会使排序不佳)算法是最佳选择;请考虑在带有磁带的机器上进行气泡排序存储)。您的假设越强,算法可以消除的角落越多。在关于如何有效地确定列表的“排序性”的非常微弱的假设下,最佳的最坏情况下的复杂度甚至可以是。Ωñ

这个答案只涉及复杂性。算法实现的实际运行时间将取决于很多因素,这些因素很难在一个答案中解决。


我猜那些应该是吗?ΩØΩ
拉斐尔

1
@Raphael Meh。我认为其中大多数都是。我认为下限可能会更好地呈现Ω。我将更换其中最有意义的几个。ΘΩ
Patrick87

7
我投@Raphael得到了警察帽子:PΩ
Realz的色拉

2
@RealzSlaw:我会很自豪地穿上它。:]
拉斐尔

1
@gen有关讨论,请参见stackoverflow.com/a/3274203。基本上,如果单个记录很大,并且不是以随机访问的方式存储的,并且数据量如此之大,则必须就地完成,那么冒泡排序就是解决之道。这些情况通常在当今很少见,但您仍然可能会遇到。
Patrick87年

16

对于此类问题,答案通常是“取决于”。它取决于(a)整数的大小,(b)输入数组是否包含随机顺序或近乎排序的整数,(c)是否需要排序算法稳定,以及其他因素,(d)整个数字列表是否适合内存(内存排序还是外部排序),以及(e)在其上运行的计算机。

在实践中,如果需要内存中的排序,则语言标准库中的排序算法可能会很好(非常接近于最佳)。因此,在实践中,只需使用标准库提供的任何排序功能,并测量运行时间。仅当您发现(i)排序是整个运行时间的很大一部分,并且(ii)运行时间是不可接受的时,才应该理会排序算法。如果这两个条件确实成立,那么您可以查看特定领域的特定方面并尝试使用其他快速排序算法。

但实际上,在实践中,排序算法很少是主要的性能瓶颈。


9

此外,回答第二个问题

从理论上讲,是否有更快的速度?
那么,排序的最低复杂度是多少?

对于通用分类,基于比较的分类问题复杂度为Ω(n log n)。有一些算法可以在O(n)中执行排序,但是它们都依赖于对输入的假设,而不是通用的排序算法。

基本上,复杂度是由对数组进行排序所需的最少比较次数给出的(log n表示在比较数组的每个元素时构建的二进制决策树的最大高度)。

您可以在此处找到排序复杂度下限的形式证明:


3
这个答案不太正确。 不是排序的通用下限。该下限仅适用于基于比较的排序,即仅使用比较的排序算法。某些排序算法不是基于比较的。语句“有一些算法可以在O(n)中执行排序,但是它们都依赖于对输入的假设,而不是通用的排序算法。” 可能有点误导-请小心。Radix-sort是一种通用的排序算法(假设您要对固定宽度的整数进行排序)。Ω(nlogn
DW

取决于您所说的排序问题。通用基于比较的排序并不是人们唯一遇到的排序问题。
Patrick87年

1
当然是这样。我应该更具体一些,谢谢指出。但是,我对您所指的其他排序方法(不是基于比较的)感到好奇。Radix Sort正是我所谈论的O(n)算法的一种-您必须“假设”有关输入的内容(固定宽度的整数)。从这个意义上讲,它不是通用的排序算法,对吗?
rla4

1
@DW:基数排序不应被视为“通用”排序算法,因为它需要固定长度的整数键;否则没有用吗?但我明白你的意思。:)我猜我的错误是集中在对可以比较的对象进行排序,而不是对整数进行排序。它们是不同的问题,并且具有不同的可能解决方案。这个问题的确提到了“整数的随机数组”,但我承认我以它为例,而不是一个限制。
rla4 2013年

2
@DavidRicherby,一年半后回头看,我同意你的看法。谢谢。
DW

3

就我遇到的最坏情况而言,最快的整数排序算法是Andersson等人的算法。它的最坏情况为,当然比O n log log n 要快。Øñ日志日志ñØñ日志ñ


2
这很有趣,但是您需要提供更多信息。由于您提到了,因此我想您知道基于比较的一般整数排序可证明需要时间Ω n log n 。渐近的任何事物都必须对数据做出假设:例如,基数排序以线性时间运行,假设数组的每个元素最多为某个常数。该算法在什么条件下以O n log log n 排序,并且在实践中如何与其他算法(例如quicksort和radix sort)进行比较?ñ日志ñΩñ日志ñØñ日志日志ñ
大卫·里希比(David Richerby)2015年

1

在撰写本文时,我通读了其他两个答案,但我认为没有一个答案能适当回答您的问题。其他答案考虑了关于随机分布和空间复杂性的无关紧要的想法,这可能超出了高中学习的范围。所以这是我的看法。

给定一个具有n个整数元素的数组,您需要在元素之间进行精确的n 1 比较,以检查A是否已排序(仅从数组的开头开始,并针对最后一个元素检查下一个元素)。实际上,n 1 )个比较是任何排序算法的最佳案例运行时间。换句话说,任何排序算法的运行时间下限都是Ω n 。如果您记得基数排序或存储桶排序,您会注意到它们的运行时间为O n一种ññ-1个一种ñ-1个Ωñ。由于所有排序算法都受 Ω n 约束,因此我认为基数排序和存储桶排序都是对整数数组进行排序的最快算法。ØñΩñ

此外,如果您不熟悉O n :两种表示法都表示该算法大约需要完成n个操作(可以是2 n3 n - 5,但不能是1n 2个操作) 。ΩñØññ2ñ3ñ-51个ñ2


是的,但运行时间也不知何故几乎欺骗,因为不断在前面ñ有效地缩放像LG的ñ(因为我们假定你是一个32位的机型,而且意味着ñ 2 32) 。因此,即使O n (用于基数排序)看起来O n lg n 好很多Øññlgññ232ØñØñlgñ(对于quicksort或mergesort),实际上比较起来不是很清楚:隐藏在big-O表示法中的常数变得非常重要,并且radix-sort的常数高于quicksort或mergesort的常数。
DW

“ n前面的常数有效地缩放为 ”我实际上不理解您用这个短语表示的意思(我知道Big-Oh表示法隐藏了对于小n可能很重要的常数)。lg(n)ñ
bourbaki4481472 2013年

我认为说任何排序算法的下限是可能是不正确的。可能存在足够自然的问题,这些假设允许您进行分类,而分类的速度甚至更快。当然,我们可能会在学术上讨论排序问题,这些问题具有更快的算法。当然,在这一点上,我们可能正在讨论实际上是什么“排序”以及问题的大小是什么,但是重点仍然是。Ωñ
Patrick87

2
Øwñwww{02w-1个}日志ññw=日志ññ日志ñ
David Richerby

1

O(nloglogn
ØñØGØGüü


0

由于您没有提到对硬件的任何限制,并且考虑到您正在寻找“最快的”,因此我想您应该根据可用的硬件和输入的种类选择一种并行排序算法。

从理论上说quick_sortO(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)

另请参阅:


Øñ2

@邪恶是的。Quicksort不太适合并行处理。这是一个例子。给定的链接中列出了应该使用的那些。
Kashyap
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.