为什么选择排序比气泡排序快?


28

维基百科写道:“ ...选择排序几乎总是胜过气泡排序和侏儒排序。” 任何人都可以向我解释为什么选择排序比气泡排序更快的原因,尽管它们都具有:

  1. 最坏情况下的时间复杂度O(n2)

  2. 比较数O(n2)

  3. 最佳案例时间复杂度

    • 气泡排序:O(n)
    • 选择排序:O(n2)
  4. 平均案件时间复杂度

    • 气泡排序:O(n2)
    • 选择排序:O(n2)

Answers:


32

您提供的所有复杂度都是正确的,但是它们以Big O表示法给出,因此将省略所有加法值和常数。

为了回答您的问题,我们需要专注于对这两种算法的详细分析。这种分析可以手工完成,也可以在很多书中找到。我将使用Knuth的《计算机编程艺术》的结果。

平均比较数:

  • 冒泡排序12(N2NlnN(γ+ln21)N)+O(N)
  • 插入排序14(N2N)+NHN
  • 选择类别(N+1)HN2N

现在,如果绘制这些函数,将得到如下所示的内容: 情节 情节2

如您所见,即使两种排序方法具有相同的渐近复杂度,气泡排序也会随着元素数量的增加而变得更加糟糕。

该分析基于以下假设:输入是随机的-可能并非总是如此。但是,在开始排序之前,我们可以随机排列输入序列(使用任何方法)以获得平均大小写。

我省略了时间复杂度分析,因为它取决于实现,但是可以使用类似的方法。


我有一个问题,“我们可以随机排列输入序列以获得平均情况”。为什么这样做比分类所需的时间更快?
Sasho Nikolov

1
您可以置换任何数字序列,这将花费次,其中是序列长度。显而易见,任何基于比较的排序算法都必须至少具有复杂度,因此即使将添加到它的复杂度也不会有太大变化。无论如何,我们谈论的不是时间,时间复杂度取决于实现和运行的机器,正如我在回答中提到的那样。N ON log N NNNO(NlogN)N
Bartosz Przybylski

我想我很困,您是对的,序列可以线性时间排列。
Sasho Nikolov

由于,您的比较绑定对于选择排序是否正确?看来您是在暗示它平均进行O(n log n)个比较。HN=Θ(logN)
templatetypedef

Gamma = 0.577216是Euler-Mascheroni的常数。相关章节是“编程的艺术”第3卷第5.2.2页。109和129。如何准确地绘制冒泡排序情况,尤其是O(sqrt(N))项?你只是忽略了吗?
mxmlnkn

11

渐近成本或数学随着函数的参数趋于无穷大(即其增长率)而描述函数的极限行为。O

如果两个算法以相同的速率增长,则函数本身(例如,比较和/或交换的次数)对于具有相同渐近成本的两种算法可能会有所不同。

更具体地说,Bubble排序平均每个条目需要交换(每个条目从其初始位置到最终位置逐元素移动,每个交换涉及两个条目),而Selection排序仅需要(找到了最小值/最大值,将其交换一次到数组末尾。1n/41

就比较次数而言,Bubble排序需要进行比较,其中是条目的初始位置与其最终位置之间的最大距离,对于均匀分布的初始值而言,通常大于。但是,选择排序始终需要比较。k n / 2 n 1 × n 2 / 2k×nkn/2(n1)×(n2)/2

总而言之,渐近限制使您对算法的成本相对于输入大小的增长方式有一个很好的了解,但是对于同一组内不同算法的相对性能则没有任何评论。


1
这甚至是一个很好的答案
Grijesh Chauhan 2013年

您喜欢哪本书?
Grijesh Chauhan 2013年

@GrijeshChauhan:书只是口味的问题,所以建议带一点盐。我个人喜欢Cormen,Leiserson和Rivest的“算法简介”,其中对许多主题进行了很好的概述;如果您需要有关特定主题的更多/所有详细信息,则喜欢Knuth的“计算机编程艺术”系列。您可能想要检查是否曾经在这里问过书本的问题,或者没有问过该书本的问题。
Pedro

对我来说,答案中的第三段是实际答案。不是其他答案中给出的大型输入的图形。
外汇兑换交易

3

冒泡排序使用更多的交换时间,而选择排序避免了这种情况。

使用选择排序时,它n最多交换一次时间。但是当使用冒泡排序时,它几乎交换n*(n-1)。显然,即使在内存中,读取时间也比写入时间短。比较时间和其他运行时间可以忽略。因此,交换时间是问题的关键瓶颈。


我认为Bartek的其他答案比较合理,但是我不能投票或发表评论……顺便说一句,我仍然认为写作时间会影响更大,希望他能看到并同意这一点。
simonmysun

您不能简单地忽略比较次数,因为在某些用例中,用于比较两个项目的时间可能远远超过交换两个项目所花费的时间。考虑一个非常长的字符串的链表(每个字符串说10万个字符)。读每个字符串要比重新分配指针花费更长的时间。
Irvin Lim

@IrvinLim我认为您可能是正确的,但在改变主意之前,我可能必须先查看统计数据。
simonmysun
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.