排序效率 算法与输入范围相关
Efficiency of sorting Algorithms as it relates to input range
我想知道典型的快速排序算法(即快速排序)在使用"非自然"输入而不是更标准的输入时是否保持其优势。
也就是说,如果我们有一个 0 到 N^4 范围内的 N 个整数数组,考虑到整数的范围非常宽,快速排序仍然是最快的吗?
快速排序不受数字范围的影响,而是受顺序的影响(即,如果数字已经排序或以相反的顺序排序,并且如果您选择第一个元素作为枢轴)。如果您使用随机透视方法,即使这个问题也可以解决。
总之,每种算法都有最坏情况的复杂性,通常在有关该算法的文献中讨论。
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)) 之间的差异可能不那么重要。
此外,对于非常昂贵的比较,例如非常大的字符串,施瓦茨变换的某些变体可能会有所帮助,并且由于每种算法都在内存和 CPU 之间平衡,因此最佳排序算法将基于使用更多内存或使用更多 CPU 之间的选择。
极端情况可能倾向于不同的排序算法,例如近似排序的列表,但通常检测这些算法的成本会很高,并且假设极端情况为真可能会导致大问题,如果
有可能它不会。说了这么多,除非绝对必要,否则所有实际实现都应该尝试将 std::sort 与相应的 std::hash 实现一起使用<>因为 std::sort 可以从多个算法中进行选择,具体取决于输入数据。
所有众所周知的搜索算法都基于元素比较,即它们检查一个元素是否小于、等于或大于另一个元素。因此,它们绝对独立于范围。
但是,在某些特殊情况下,某些算法的相对性能可能与平均情况有很大差异。此类案例的示例包括:
- 除单个元素或小子集外,元素已排序。
- 元素的顺序相反。
- 除一个元素外,所有元素都是相等的。
这就是为什么对于每种排序算法,都可以确定平均和最坏情况的性能。
其他答案基本上是正确的,因为通常排序算法不会根据输入的范围而更好或更差。但是,根据输入范围,算法可能更好或更差至少有一个原因,那就是它们如何处理重复值。
例如,当重复值较多时,快速排序平均更差(有关原因的说明,请参阅此问题),当输入范围较大时,重复的可能性降低(假设它们分布在整个范围内)。
- ";结果类型必须是可从输入范围的值类型""构造的;创建std::vector时
- 我有一个数组,我想输入一个范围,然后找到范围内所有偶数的总和?
- 程序中的布尔函数返回输入的范围无论如何都是无效的
- 在这个无限循环中,当输入 0 时终止,当输入 int 范围之外的任何内容时,程序行为不正常
- 如何按升序对输入文件中的数字进行排序,并找到它们的范围和中值
- 是否有一种方法可以避免标头文件中使用的constexpr函数输入全局范围,而无需额外的名称空间
- 从用户输入范围内输出质量数量
- 我正在尝试创建一个程序,用户在其中输入一系列数字,并且我想列出范围之间的质数
- 循环直到整数输入在所需范围内无法处理非数字字符输入
- 基于范围的输入流循环
- 扩展编译器以在编译时计算"complicated"函数(具有已知的输入值),超出"constexpr"的范围
- <algorithm>在同一输入迭代器范围内并排运行两个
- 我正在尝试确定用户输入有序对的域和范围
- 在此范围内未声明"输入"
- 错误输入未在此范围中显示
- 排序效率 算法与输入范围相关
- 只允许在QDoubleValidator的范围内输入QLineEdit
- 无法正确验证无效输入并接受带有C++的正确范围值
- 在C++中实现随机预言机(输出在范围内是随机的,但对于相同的输入输出是相同的)
- 检查输入是否在其C++限制范围内