插入排序与冒泡排序算法

时间:2013-06-24 08:02:47

标签: algorithm sorting

我正在尝试理解一些排序算法,但我很难看到冒泡排序和插入排序算法的差异。

我知道两者都是O(n 2 ),但在我看来,冒泡排序只会将每个过程中数组的最大值冒泡到顶部,而插入排序只会下降到最低价值到底每一遍。他们不是在做同样的事情而是在不同的方向吗?

对于插入排序,比较/潜在互换的数量从零开始并且每次都增加(即0,1,2,3,4,...,n),但是对于冒泡排序,这种情况会发生,但是排序结束(即n,n-1,n-2,... 0),因为冒泡排序不再需要与排序后的最后一个元素进行比较。

尽管如此,似乎一致认为插入排序更好。谁能告诉我为什么?

编辑:我主要对算法的工作方式不同感兴趣,而不是效率或渐近复杂度。

11 个答案:

答案 0 :(得分:99)

插入排序

i 迭代之后,第一个 i 元素被排序。

在每次迭代中,下一个元素通过排序部分冒泡,直到它到达正确的位置:

sorted  | unsorted
1 3 5 8 | 4 6 7 9 2
1 3 4 5 8 | 6 7 9 2

4被冒泡到排序部分

伪代码:

for i in 1 to n
    for j in i downto 2
        if array[j - 1] > array[j]
            swap(array[j - 1], array[j])
        else
            break

冒泡排序

i 迭代之后,最后的 i 元素是最大的,并且是有序的。

在每次迭代中,筛选未排序的部分以找到最大值。

unsorted  | biggest
3 1 5 4 2 | 6 7 8 9
1 3 4 2 | 5 6 7 8 9

5从未分类的部分冒出来

伪代码:

for i in 1 to n
    for j in 1 to n - i
         if array[j] > array[j + 1]
             swap(array[j], array[j + 1])

请注意,如果在外部循环的一次迭代期间没有进行交换,则典型的实现会提前终止(因为这意味着数组已经排序)。

差分

在插入中,排序元素会冒泡到已排序的部分,而在冒泡排序中,最大值会从未排序的部分冒出来。

答案 1 :(得分:28)

在第i次迭代的冒泡排序中,你有ni-1内迭代(n ^ 2)/ 2总数,但是在插入排序中,你在第i步上有最大的i次迭代,但平均而言是i / 2,你可以在找到当前元素的正确位置后,先停止内循环。所以你有(总和0到n)/ 2总共(n ^ 2)/ 4;

这就是为什么插入排序比冒泡排序更快的原因。

答案 2 :(得分:15)

另一个不同之处,我在这里没有看到:

冒泡排序每次展开 3个值分配: 你必须首先建立一个临时变量来保存你想要推进的值(1号),而不是你必须将另一个交换变量写入你刚刚保存的值(第2号),然后你必须在现场其他地点(3号)写你的临时变量。 你必须为每个点做到这一点 - 你想要前进 - 将你的变量排序到正确的位置。

使用插入排序,您可以将变量放入临时变量中,然后将所有变量放在该位置前面的1个位置,只要您到达变量的正确位置即可。这使每个点 1值分配。最后,你将临时变量写入现场。

这样做的价值也远低于此。

这不是最强的速度效益,但我认为可以提及。

我希望,我表达自己可以理解,如果没有,对不起,我不是英国人

答案 3 :(得分:7)

插入排序的主要优点是它是在线算法。您不必在开始时拥有所有值。在处理来自网络或某些传感器的数据时,这可能很有用。

我有一种感觉,这会比其他传统的n log(n)算法更快。因为复杂性为n*(n log(n)),例如读取/存储流(O(n))中的每个值,然后对所有值(O(n log(n)))进行排序,从而生成O(n^2 log(n))

相反,使用Insert Sort需要O(n)来读取流中的值,O(n)将值放到正确的位置,因此它只是O(n^2)。另一个优点是,您不需要缓冲区来存储值,您可以在最终目的地对它们进行排序。

答案 4 :(得分:7)

冒泡排序不在线(它不能在不知道将有多少项目的情况下对输入流进行排序),因为它并不真正跟踪已排序元素的全局最大值。插入项目时,您需要从头开始冒泡

答案 5 :(得分:4)

只有当有人从大型数字列表中查找前k个元素时,才能使冒泡排序优于插入排序 即在k次迭代后进行冒泡排序,你将获得前k个元素。但是,在插入排序中进行k次迭代后,它只能确保对这些k元素进行排序。

答案 6 :(得分:2)

虽然这两种排序都是O(N ^ 2)。隐藏常量在插入排序中要小得多。隐藏常量是指实际执行的基本操作数。

当插入排序有更好的运行时间?

  1. 数组几乎已经排序 - 请注意,插入排序在这种情况下执行的操作少于冒泡排序。
  2. 数组的大小相对较小:插入排序你移动元素,放置当前元素。如果元素数量很少,这只比冒泡排序更好。
  3. 请注意,插入排序并不总是比冒泡排序更好。为了获得两全其美,如果数组的大小很小,可以使用插入排序,并且可能为较大的数组合并排序(或快速排序)。

答案 7 :(得分:2)

在所有情况下,冒泡排序几乎无用。在插入排序可能有太多交换的用例中,可以使用选择排序,因为它保证少于N次交换。因为选择排序比冒泡排序更好,所以冒泡排序没有用例。

答案 8 :(得分:2)

插入排序:

1。在插入排序中,不需要交换。

2。插入排序的时间复杂度在最佳情况下为Ω(n),在最坏情况下为O(n ^ 2)。

与气泡排序相比,复杂度降低了

4.example:将书插入图书馆,整理卡片。

气泡排序: 1.气泡排序需要交换。

2。最佳情况下,气泡排序的时间复杂度为Ω(n),最坏情况下为O(n ^ 2)。

3。与插入排序相比更复杂。

答案 9 :(得分:1)

每次迭代中的交换次数

  • 插入排序在每次迭代中最多1次交换
  • 冒泡排序在每次迭代中执行0到n交换。

访问和更改已排序的部分

  • 对已排序的部分进行插入排序访问(以及在需要时进行更改)以查找正确考虑的数字位置。
  • 优化后,冒泡排序不会访问已经排序的内容。

在线与否

  • 插入排序在线。这意味着插入排序在放入适当的位置之前,一次一次输入。它不必仅比较adjacent-inputs
  • 冒泡排序不在线。它不能一次操作一个输入。它在每次迭代中处理一组输入(如果不是全部)。冒泡仅在每次迭代中进行比较并交换adjacent-inputs

答案 10 :(得分:0)

插入排序可以恢复为“查找应该位于第一个位置的元素(最小值),通过移动下一个元素来创建一些空间,并将其放在第一个位置。好。现在看一下元素应该在第二...... “等等......

冒泡排序操作不同,可以恢复为“只要我发现两个相邻元素的顺序错误,我就交换它们”。