排序算法的效率与输入范围有关

时间:2016-02-29 19:21:08

标签: c++ algorithm sorting

我想知道典型的快速排序算法(即快速排序)是否在不自然的情况下保持其优势。使用输入而不是更标准的输入。

I.E,如果我们有一个0到N ^ 4范围内的N个整数数组,那么对于极宽范围的整数,quicksort仍然是最快的吗?

4 个答案:

答案 0 :(得分:1)

Quicksort不会受到数字范围的影响,但是顺序(即如果数字已经按相反顺序排序或排序,并且您选择第一个元素作为数据透视)。如果您使用随机数据透视方法,即使该问题也已解决。

总之,每种算法都具有最差的案例复杂性,并且通常在文献中讨论该算法。

答案 1 :(得分:1)

N ^ 4不是很大,20亿个整数的数组每个整数只需要128位来满足该要求。由于这需要至少8GB存储在内存中,因此通常会限制为可以排序的O(N * log(N))排序算法,如快速排序,而不是需要两次的O(N)算法尽可能多的记忆。

允许O(N)的算法(在最好的情况下,这里不太可能)通常会被内存限制。给定的示例,基数排序,变为具有大数据元素的O(N log(N)),因为数据实际上是可变长度 - 考虑一个32,768字节的整数 - 在64位计算机上,您的第一个桶可能是基于前8个字节,第二个8字节的第二个桶,但由于存储桶内的非常大的可能范围和非随机分布,大多数桶都很小,留下一些非常大的桶用于分类O(N log(N))算法。此外,该算法需要分配“桶”来保存每个基数的元素,这将使总内存需求翻倍。

对于需要非常昂贵的比较的小元素列表,基数排序可能是一个不错的选择,但O(N)和O(N log(N))之间的差异对于小列表可能不那么重要。

此外,由于非常昂贵的比较,例如非常大的字符串,Schwartzian变换的某些变化可能会有所帮助,并且由于每个算法在内存和cpu之间进行平衡,因此最佳排序算法将基于使用之间的选择更多内存或使用更多cpu。

极端情况可能有利于不同的排序算法,例如接近排序的列表,但通常检测这些算法的成本会很高,并假设极端情况属实,如果有可能会导致大问题它不会。

说完所有这些之后,所有实际的实现都应该尝试使用std :: sort和std :: hash<>的相应实现。除非绝对必要,否则std :: sort可以从多个算法中选择,具体取决于输入数据。

答案 2 :(得分:0)

所有众所周知的搜索算法都基于元素比较,即它们检查元素是否小于,等于或大于另一个元素。因此它们完全独立于范围。

然而,在某些特殊情况下,某些算法的相对性能可能与普通情况有很大不同。这种情况的例子是:

  • 除了单个元素或小子集之外,元素已经被排序。
  • 元素的顺序相反。
  • 除一个元素外,所有元素都相同。

这就是为什么对于每种排序算法,可以确定平均和最坏情况的性能。

答案 3 :(得分:0)

其他答案基本上是正确的,因为基于输入的范围,通常排序算法不会更好或更差。但是,基于输入范围,算法可能更好或更差的原因至少有一个,这就是它们处理重复值的方式。

例如,当存在更多重复值时,Quicksort的平均值会更差(请参阅this question了解原因),当输入范围更大时,重复的可能性会降低(假设它们是分布式的)在整个范围内)。