【问题标题】:When are simple sorts faster than 'complex' sorts?什么时候简单排序比“复杂”排序更快?
【发布时间】:2014-02-26 17:20:01
【问题描述】:

我在学校得到了一个排序算法作业,我们的任务是复习几种排序算法。该报告的一个部分是关于“什么时候简单排序更快”。

我的排序算法是:

  • 冒泡排序
  • 选择排序
  • 插入

都是 O(n^2) 平均

然后我有以下 O(n log n) 算法:

  • 归并排序
  • 快速排序

和基数排序 O(kn)

我已经对未排序和排序的数据进行了多次测试,范围从 10 到 100,000 的 n 个条目,并且总是在更快的时间内执行复杂的排序 O(n log n)。

我还尝试使用包含 n 个元素的排序数据集,其中 n = 10 到 n = 100,000

但 O(n log n) 算法仍然更快。

所以我的问题是,什么时候简单的排序比复杂的排序更快。

谢谢, 克里斯。

【问题讨论】:

  • 记住 C。对于 small N,小的 C 可以加快挂钟时间。这就是为什么类似快速排序的实现可能对叶子使用冒泡排序的原因。 (如果 n=10 上的冒泡排序不是更快,或者至少相当,我几乎会怀疑这些实现——当我为学校 n=20 做一个类似的研究项目时,它是关于冒泡/快速排序的截止点,但它也可能是编译器/CPU 的差异。)
  • 基数排序不是 O(n log n)。 en.wikipedia.org/wiki/Radix_sort
  • 使用真正的小输入。 n 从 2 开始。
  • 你是如何安排这些时间的?
  • @TimothyShields ye 我的错误是 O(nk) 抱歉

标签: algorithm sorting


【解决方案1】:

运行时间与输入大小的平方成正比的排序的内部循环内的分支往往非常简单。

在这方面,插入排序通常效果最好。

另一方面,对于大小为 N 的输入,运行时间与 N log N 成正比的排序具有更复杂的分支。

分支复杂度显示为运行时间中的一个常数因素。所以我们有简单和复杂的运行时间

S N^2  and  C N log N

在较旧的计算机上,S 往往比 C 小很多。假设你有 S = 1 和 C = 4,那么你就有一个可以求解的方程:

1 N^2 = 4 N log N

感兴趣的解在 N = 16 处(对数以 2 为底)。这是输入的大小,其中“简单”算法具有的更好速度的常数因子被更好的渐近速度所克服。小于 16 的输入将被单算法更快地排序!当 N > 16 时,复杂算法的威力“开始发挥作用”。

然而,在现代计算机中 - 正如您所发现的那样 - 在硬件级别更快的分支和更好的编译器使 S 和 C 更接近。根据我的经验,关于 N^2 类运行速度更快的古老传说仅适用于微型嵌入式处理器。

【讨论】:

    【解决方案2】:

    这实际上取决于算法的特定实现。通常,对于 0 和低 10 个元素之间的 n,插入排序将击败大多数 O(n log n) 排序,但实际数量取决于插入排序的实现方式、数据的排序方式、比较的成本等. 在这种情况下,您几乎必须相互运行排序算法的特定实现,以确定何时哪个更快。

    希望这会有所帮助!

    【讨论】:

    • 我还要补充一点,它在某种程度上取决于被排序的数据元素的大小——对于那些交换元素的算法,一个 32 位整数元素或指针元素可以移动很多比 64KB 的数据块更快(假设数据具有有意义的比较操作——比如一个巨大的整数实现之类的东西)......
    【解决方案3】:

    首先,基数排序不是O(nlogn)。它是O(kn),其中 k 是任何数字中的最大位数。

    O(n^2) 排序可能比O(nlogn) 排序更快

    1. 输入的大小很小。如果您的输入包含~100(甚至~1000)个数字,现代处理器可以显示O(n^2) 排序更快(或与O(nlogn) 相同)。

    2. 在某些情况下,O(n^2) 排序可能会在它识别出要排序的数组时在其排序中间停止,这在 O(nlogn) 排序的情况下很难(但仍然可能)实现。

      例如,在插入排序或标记冒泡排序中,如果数组已排序,则可以停止算法。这会产生最佳情况下的O(n) 性能。

    【讨论】:

      【解决方案4】:

      如果输入很小或者输入几乎是排序的,那么“简单”排序算法工作得很好。

      【讨论】:

        【解决方案5】:

        要获得这个问题的答案,您首先要了解 Big O 的工作原理。

        10000 n^2 是 O(n^2) 10 n^3 是 O(n^3)

        所以我们说 n 是 2

        那么 10 n^3 将比 10000 n^2 更快。

        但假设你不知道 n 的长度或者 n 可能真的很大,那么 10000 n^2 会更好

        【讨论】:

          【解决方案6】:

          我的问题是,什么时候简单的排序比复杂的排序更快。

          一般来说很难说;太多取决于实现细节、数据和硬件等。

          但是,我可以举一个实际的例子。快速排序的复杂度为 O(n*log(n)),插入排序的平均复杂度为 O(n2),请参阅 Sorting in Wikipedia。然而,仍然值得在快速排序中切换到对微小子数组的插入排序,请参阅 Cutoff to insert sort in Algorithms by Sedgewick & Wayne(第 4 版中的第 296 页)。他们声称“在大多数情况下,5 到 15 之间的任何值都可能很好用。”生成的算法比单独的快速排序或插入排序要好。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-11-30
            • 1970-01-01
            • 2018-03-28
            • 2019-02-26
            • 2012-08-23
            • 2018-05-24
            • 2011-04-02
            • 1970-01-01
            相关资源
            最近更新 更多