插入排序比冒泡排序好?

Posted

技术标签:

【中文标题】插入排序比冒泡排序好?【英文标题】:Insertion sort better than Bubble sort? 【发布时间】:2012-05-12 18:55:21 【问题描述】:

我正在为考试做复习。

想知道在 O(N^2) 的平均情况复杂度相同的情况下,插入排序在什么条件下会比冒泡排序表现更好。

我确实找到了一些相关的文章,但我看不懂。

有人介意用简单的方式解释一下吗?

【问题讨论】:

【参考方案1】:

冒泡排序的优势在于检测已排序列表的速度:

BubbleSort 最佳案例场景:O(n)

但是,即使在这种情况下,插入排序也能获得更好/相同的性能。

冒泡排序或多或少只有助于理解和/或教授排序算法的机制,但现在在编程中找不到合适的用法,因为它很复杂

O(n²)

意味着它的效率在元素数量超过少数的列表上会急剧下降。

【讨论】:

“冒泡排序仅有助于理解和/或教授排序算法的机制”——我想说的是。插入排序并不难理解,也不难编码。冒泡排序有一个非常特殊的优势,那就是它被证明是对于没有随机访问的特定类型的存储最有效的排序。我认为,鼓存储,其中鼓仅在一个方向上以恒定速度旋转。然后它击败了插入排序,因为插入排序需要“向后看”,这非常慢。如今,这种优势很少有实际用途!【参考方案2】:

我想到了以下事情:

    冒泡排序总是需要多遍历一次数组来确定它是否已排序。另一方面,插入排序不需要这个——一旦插入最后一个元素,算法就保证数组是排序的。

    冒泡排序在每次通过时都会进行n 比较。插入排序少于n 比较:一旦算法找到插入当前元素的位置,它就会停止比较并获取下一个元素。

    最后引用wikipedia文章:

冒泡排序与现代 CPU 硬件的交互也很差。它 需要至少两倍于插入排序的写入次数,两倍于 许多缓存未命中,以及渐近更多的分支错误预测。 Astrachan 在 Java 中对字符串进行排序的实验显示冒泡排序 大约比插入排序慢 5 倍,比插入排序慢 40% 选择排序

您可以在此处找到原始研究论文的链接。

【讨论】:

感谢维克多。我发现前 2 点非常有用。我现在明白这两种算法之间的一个根本区别是所需的比较次数。干杯 第二点似乎不正确。是的,一些算法可以做到这一点。但我认为在正确的冒泡排序算法中,内循环在外循环的每次迭代中运行 n-1、n-2、n-3 .... 次。【参考方案3】:

我猜你正在寻找的答案是here:

冒泡排序也可以有效地用于已经存在的列表 除极少数元素外已排序。例如,如果 只有一个元素不按顺序排列,冒泡排序只需 2n 次。 如果两个元素不按顺序排列,冒泡排序最多只取 3n 次...

插入排序是一种相对简单的排序算法 对小列表和大多数排序列表有效,并且经常使用 作为更复杂算法的一部分

【讨论】:

例如一个主要排序的列表:例如[ 2,3,4,5,1] 冒泡排序需要 4 次交换和 4 次比较 插入排序也需要 4 次交换和 4 次比较。那么有什么区别呢? 在那个特定的例子中没有区别:)【参考方案4】:

能否提供您不理解的相关文章的链接?我不确定他们可能会解决哪些方面的问题。除此之外,还有一个理论上的区别可能是冒泡排序更适合表示为数组的集合(而不是表示为链表的集合),而插入排序更适合链表。

原因是冒泡排序总是一次交换两个项目,这在数组和链表上都是微不足道的(在数组上更有效),而插入排序在给定列表中的一个位置插入,这对于链表来说微不足道列表,但涉及将数组中的所有后续元素向右移动。

话虽如此,但还是持保留态度。首先,实际上,排序数组几乎总是比排序链表快。仅仅因为扫描一次列表已经有很大的不同。除此之外,将数组的 n 个元素向右移动比执行 n(甚至 n/2)交换要快得多。这就是为什么其他答案正确地声称插入排序总体上是优越的,以及为什么我真的想知道您阅读的文章,因为我想不出一种简单的方式来说明这在案例 A 中更好,而在案例 A 中更好B.

【讨论】:

冒泡排序可能比冒泡排序更适合链表,但冒泡排序并不比插入排序更适合数组。 是的,也许我在最后一段中不够清楚。问题是,冒泡排序在概念上在数组上是微不足道的,而插入排序则不是(“将所有内容从 x 向右移动”)。尽管如此,这并没有使冒泡排序更快。【参考方案5】:

在最坏的情况下,两者都倾向于在 O(n^2) 时执行

在最好的情况下,即当数组已经排序时,冒泡排序可以在 O(n) 时执行。

【讨论】:

冒泡排序可以优化为在 O(n) 的运行时间内运行以获得最佳情况。 对于最坏/平均/最佳情况的性能,气泡和插入都具有相同的复杂度,即 O(n^2),而且空间复杂度对它们来说都是 O(n)。 @LeventDivilioglu 在最好的情况下,冒泡排序可以在 O(n) 处执行。我们可以修改冒泡排序,如果在第一次迭代期间没有发生交换,那么我们可以停止检查,因为列表已经排序。

以上是关于插入排序比冒泡排序好?的主要内容,如果未能解决你的问题,请参考以下文章

同样的复杂度,为什么插入排序比冒泡排序更受欢迎?

11 | 排序(上):为什么插入排序比冒泡排序更受欢迎?

JavaScript 数据结构与算法之美 - 冒泡排序插入排序选择排序

11 | 排序(上):为什么插入排序比冒泡排序更受欢迎?

为什么插入排序比冒泡排序更受欢迎?

Java数据结构和算法——冒泡选择插入排序算法