打字猫

从算法到算命—八大排序算法之冒泡排序篇

从算法到算命—八大排序算法之冒泡排序篇

核心思想

两两交换,更大(小)的往后(前)放

算法描述

  • 比较相邻的元素。如果第一个比第二个大(小),就交换它们两个;
  • 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大(小)的数;
  • 针对所有的元素重复以上的步骤,除了最后一个;
  • 重复步骤1~3,直到排序完成。

动图演示

以升序为例:

排序过程

首先,我们先来构建一个初始无序的数组,数组内元素与之前的的一致。

image

那么,我们说冒泡排序是两个元素相互比较交换,我们要实现的是一个升序的排序过程,所以更大的元素应该往后放。我们来看看第一遍的过程:

首先 4938 进行比较,因为49 大于 38 ,所以我们将两个元素交换位置,此时变成:

image

此时我们看下一对需要比较的元素,分别是 4965 ,因为49 小于 65 ,所以这两个元素我们不需要交换彼此的位置,此时应为:

image

下一对元素 6597 相比,因为65 小于 97 ,同理我们不需要交换彼此的位置,此时应为:

image

下一对元素 9776 相比,因为 97 大于 76 ,所以两个元素需要交换彼此的位置,此时应为:

image

下一对元素 9713 相比,因为 97 大于 13 ,所以两个元素需要交换彼此的位置,此时应为:

image

下一对元素 9727 相比,因为 97 大于 27 ,所以两个元素需要交换彼此的位置,此时应为:

image

最后一对元素 9749 相比,因为 97 大于 49 ,所以两个元素需要交换彼此的位置,此时应为:

image

那么至此,第一趟循环执行完毕了,我们可以看到,最大的元素 97 就像吐泡泡一样,一点一点冒到了最后一个位置。接下来,就是一个不断重复的过程:

在第二趟中,我们先看, 3849 对比,顺序不用改变, 4965 对比,顺序不用改变。

6576 对比,顺序不用改变, 7613 对比,顺序需要改变:

image

下一对元素 7627 相比,因为 76 大于 27 ,所以两个元素需要交换彼此的位置,此时应为:

image

下一对元素 7649 相比,因为 76 大于 49 ,所以两个元素需要交换彼此的位置,此时应为:

image

那么此时,我们第二趟也执行完毕,已将将 76 冒到了后面的位置,接下来继续执行下一次循环:

image

至此,第三趟循环已经完成,我们将 65 这个元素冒到了对应的位置,接下来继续重复之前的操作:

那么第四趟循环应该是将第一个出现的 49 向后进行位置交换,直到找到第二个 49 出现,停止循环,结果如下:

image

此时我们发现,其实下次循环过后,将 38 冒到 27 后面,就是一个有序的数组了,执行过程依旧如上,两两进行交换,那么第五趟循环的结果应为最终结果,数组元素排列次序如下:

image

至此,我们整个排序过程就结束了,可以看到, 4949 排序前和排序后位置没有发生改变,所以我们说,冒泡排序也是一个稳定的排序,插帽龟嘛,都是稳定的。

代码示例(Java)

@Test
public void bubbleSort() {
    int[] arr = {49, 38, 65, 97, 76, 13, 27, 49};
    int n = arr.length - 1;
    for (int i=0; i<n; i++) {
        //如果左边大于右边则将他们调换位置
        for (int j = 0; j < n - i; j++) {
            if (arr[j] > arr[j + 1]) {
                arr[j] ^= arr[j + 1];
                arr[j + 1] ^= arr[j];
                arr[j] ^= arr[j + 1];
            }
        }
    }
}

冒泡排序特性总结

  1. 冒泡排序是一种非常容易理解的排序

  2. 时间复杂度:

    ​ 最坏情况 -> 数组逆序:O(N2) (双重循环,每轮排序要比较n次,并且重复n次)

    ​ 最好情况 -> 数组顺序:O(N)(最少得执行一次内层循环)

  3. 空间复杂度:O(1)

  4. 稳定性:稳定

posted @ 2023-09-16 19:03  我还是我吗?  阅读(16)  评论(0编辑  收藏  举报