【问题标题】:is selection sort faster than insertion for big arrays? [duplicate]选择排序比插入大数组更快吗? [复制]
【发布时间】:2012-12-02 19:27:47
【问题描述】:

可能重复:
Efficency of Insertion Sort vs Bubble sort vs Selection sort?

选择排序比插入大数组更快吗?最坏的情况是什么时候?

我知道插入比选择快,但对于大型数组和最坏的情况?

【问题讨论】:

  • 先生,我说的是大型阵列
  • 编写一个程序并测试它。然后请说我们在这里回答这个问题。
  • 数组越大,渐近 O() 行为越重要,单个操作的成本就越不重要。

标签: algorithm sorting insertion-sort


【解决方案1】:

所涉及的数组的大小很少有太大的影响。

真正的问题是比较与复制的速度。选择排序获胜的时间是比较比复制快很多。举个例子,让我们假设两个字段:一个 int 作为键,另外一个 MB 的数据附加到它上面。

在这种情况下,比较只涉及单个 int,因此速度非常快,但复制涉及整个兆字节,因此几乎可以肯定会慢一些。

由于选择排序做了很多比较,但比较少的副本,这种情况将有利于它。插入排序会做更多的副本,所以在这种情况下,较慢的副本会减慢很多。

就选择排序的最坏情况而言,情况恰恰相反——复制速度快但比较速度慢的任何情况。

【讨论】:

  • 这是不正确的,数组的大小为N,与O(N)有关。如果算法的复杂度为 O(N*N),那么数组的大小是最重要的。
  • @AlexWien:是的,但在这种情况下,我们正在比较 both O(NN) 的算法。如果我们比较具有不同复杂度的算法(例如,O(NN) 到 O(N log N),那么数组的大小将很重要,但在比较选择排序和插入排序时基本上没有。
  • 即便如此,大 O 表示法也无济于事。因为 c1*O(N) 可以大于 c2*O(N*N)。大 O 表示法不考虑因子 c。实际上,这是一个实现细节:如果您可以使用 memcopy,那么您可以移动 1000 个元素,比两个交换 2 个元素更快
【解决方案2】:

根据Wikipedia article

一般来说,插入排序会写入数组 O(n2) 次, 而选择排序只会写入 O(n) 次。为此原因 在写入内存的情况下,选择排序可能更可取 比读取贵得多,例如使用 EEPROM 或 闪存。

无论数组大小如何,这都是正确的。事实上,随着数组变大,差异会更加明显。

【讨论】:

  • @user1516883 你不知道哪个更快,这取决于机器。内存访问很重要。移动整个数组的 memcopy 可能比两个条目的单个交换更命运。这就是为什么 java 中的 LinkedList 比 ArrayList 慢的原因。
  • 不,这与数组大小无关。您忘记了 O(N) 意味着 cO(N) 并且在插入排序中使用 memcopy 时 c 非常低。 c1*O(n) 可以大于 c2 * O(NN)
  • @user1516883:是的,一般来说插入排序会更快。但是,这取决于内存访问的速度。维基百科的文章确实很好地解释了事情。
【解决方案3】:

插入排序,如果实施得当,使用 memcpy() 移动其他值。所以它取决于处理器、缓存速度(第一级 2 级缓存)、缓存大小,当一个算法变得比另一个更快时。

我记得有一个实现(是 java 吗?)当元素的数量没有超过特定的硬编码阈值时使用一种算法,否则使用另一种算法。

因此,您只需测量它。 大 O 表示法对于中小型数组有点误导,那么 O(N) 表示 c * O(N)。 而因素 c 会影响总执行时间。

【讨论】:

    猜你喜欢
    • 2016-06-03
    • 2015-11-10
    • 1970-01-01
    • 2019-02-26
    • 1970-01-01
    • 2014-05-17
    • 1970-01-01
    • 2011-11-30
    • 2023-02-05
    相关资源
    最近更新 更多