C++ 与输入范围相关的排序算法的效率

C++ 与输入范围相关的排序算法的效率,c++,algorithm,sorting,C++,Algorithm,Sorting,我想知道当使用“非自然”输入而不是更标准的输入时,典型的快速排序算法(即快速排序)是否能保持其优越性 也就是说,如果我们有一个在0到N^4范围内的N个整数数组,那么如果整数的范围非常大,快速排序还会是最快的吗 快速排序不受数字范围的影响,但受顺序的影响(即,如果数字已按相反顺序排序或排序,并且选择第一个元素作为轴心)。如果您使用的是随机轴心方法,即使这个问题也会得到解决 总之,每种算法都有一个最坏情况复杂度,并且通常在关于该算法的文献中讨论。所有著名的搜索算法都基于元素比较,即它们检查一个元素是

我想知道当使用“非自然”输入而不是更标准的输入时,典型的快速排序算法(即快速排序)是否能保持其优越性


也就是说,如果我们有一个在0到N^4范围内的N个整数数组,那么如果整数的范围非常大,快速排序还会是最快的吗

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


总之,每种算法都有一个最坏情况复杂度,并且通常在关于该算法的文献中讨论。

所有著名的搜索算法都基于元素比较,即它们检查一个元素是否小于、等于或大于另一个元素。因此,它们绝对独立于范围

然而,在某些特殊情况下,某些算法的相对性能可能与平均情况有很大差异。例如:

  • 除单个元素或小子集外,元素已排序
  • 元素的顺序相反
  • 除一个元素外,所有元素都相等

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

N^4不是很大,一个20亿个整数的数组只需要每个整数128位就可以满足这一要求。由于这将需要至少8GB的内存存储空间,因此通常只能使用O(N*log(N))排序算法进行就地排序,如快速排序,而不是O(N)排序算法需要两倍的内存

允许O(N)(在最佳情况下,这里不太可能)的算法通常会受到内存的限制。给定的例子,基数排序,成为O(n log(n))的大数据元素,因为数据是有效可变长度-考虑一个32768字节的整数-在64位机器上,你的第一个桶可能是基于前8个字节,第二个桶在第二个8字节,但由于桶内的可能范围非常大且非随机分布,大多数桶都很小,剩下一些非常大的桶需要使用O(N log(N))算法进行排序。此外,该算法需要分配“bucket”来保存每个基数的元素,这将使总内存需求增加一倍

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

此外,对于非常昂贵的比较,例如非常大的字符串,施瓦茨变换的一些变化可能会有帮助,并且由于每个算法在内存和cpu之间保持平衡,因此最佳排序算法将基于使用更多内存还是使用更多cpu之间的选择

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


话虽如此,除非绝对必要,否则所有实际实现都应该尝试将std::sort与std::hash的相应实现一起使用,因为std::sort可以根据输入数据从多个算法中进行选择。

其他答案基本正确,在这种情况下,排序算法通常不会根据输入的范围而变得更好或更差。然而,至少有一个原因可以解释一个算法根据输入范围的好坏,那就是它们如何处理重复值


例如,当存在更多重复值时,快速排序的平均效果更差(请参阅以了解原因的解释),当输入范围更大时,重复的可能性降低(假设它们分布在整个范围内)

我知道一个办法。测试它。我更多的是从理论的角度思考-以及为什么范围可能会或可能不会影响运行时。从自己学习一些排序算法开始。可能会实施一些。这个问题清楚地表明你对排序算法一点也不了解。在[0,N^4]中整数的特殊情况下,你可以在四个过程中解释它们的base-N和基数排序--O(N)。