冒泡排序详解

本文详细介绍了冒泡排序的原理、应用场景、思想及步骤。通过实例展示了冒泡排序的Java实现,并针对效率进行了两次优化,分别是设置标记判断序列是否已排序和记录最后交换位置。冒泡排序虽然时间复杂度较高,但在小规模排序和教学中仍有一定价值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、什么是冒泡排序?

        冒泡排序是一种交换排序算法,主要是序列中的相邻元素之间比较和位置交换,这会导致序列中小(大)的元素慢慢的“浮向”序列的右端,从而导致序列降序(升序),就像水中的气泡一样,所以称为“冒泡排序”。

2、什么情况可以使用冒泡排序?

        冒泡排序比较简单,但是时间复杂度较大,使用于小规模的排序或者教学。

3、冒泡排序的思想是什么?

        冒泡排序的思想是:通过相邻元素的比较和位置交换,使得每次遍历都可以得到剩余元素中的最大值或者最小值,将其放入有序序列中正确的位置。

4、冒泡排序的步骤是什么?

        冒泡排序(升序)步骤:

        1. 取无序的序列中的第一个和第二个元素比较,将其中较大的排在右边,较小的排在左边。 比较序列中的第二个和第三个,将其中较大的排在右边,较小的排在左边。类推后面的元素。 比较倒数第二个和倒数第一个,将其中较大的排在右边,较小的排在左边。由此会导致序列中的最大值放在了序列的最后。

        2. 将除最后元素的序列作为一个新的序列,重复步骤1导致序列中的最大值放到序列倒数第二个元素。以此类推即可。直到新的序列中只有一个元素,即可得到一个升序的序列。

5、冒泡排序的Java代码

        普通的冒泡算法:

private static void BubbleSort(int[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }

        普通冒泡算法存在问题,当我们给出的序列是有序的时候,普通的冒泡算法会在第一次遍历后进行无效的比较,所以我们可以设置一个标记,当我们进行第一次比较的时候,没有进行相邻元素的交换,说明原来的序列是有序的,我们不用进行后面的比较,由此我们优化了代码。例如:给出的序列是{1,2,3,4,5},本来就是有序的,我们使用标记可以只用遍历一次,时间复杂度为O(n)

        冒泡排序优化一版:

 private static void BubbleSort(int[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            // 标记:用于标记第一次遍历是否存在位置交换,如果没有说明原本有序
            boolean flag = true;
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                    flag = false;
                }
            }
            if (flag) {
                return;
            }
        }
    }

        冒泡排序优化一次后还是存在一点问题,如果冒泡排序遍历几次后,某次遍历中,最后一次交换位置后,还存在一些元素,这些元素不用交换位置,说明其已经是有序的可以不用比较了,此时我们可以记录下遍历中最后一个交换元素的位置,其后的元素不用,比较,以此减少无效的比较。比如某次遍历后序列为{2,3,1,4,5,6},后面的4,5,6可以不用比较,它们已经是有序的了。

        冒泡排序优化二版:

 private static void BubbleSort(int[] arr) {
        int length = arr.length - 1;
        int tempFlag = 0;
        for (int i = 0; i < arr.length - 1; i++) {
            // 标记:用于标记第一次遍历是否存在位置交换,如果没有说明原本有序
            boolean flag = true;
            for (int j = 0; j < length; j++) {
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                    flag = false;
                    // 用于存放最后一次交换前一个元素的索引,
                    // 就j<length,所以j+1是可以得到j索引位置的元素的
                    tempFlag = j;
                }
            }
            length = tempFlag;
            if (flag) {
                return;
            }
        }
    }

6、冒泡排序的总结

        总结如下:

  1. 冒泡排序的时间复杂度为O(n²),最好的时间复杂度为O(n),参照优化一版,空间复杂度为O(1)。
  2. 冒泡排序是稳定性排序(是否稳定性参照排序前后,相同元素的相对位置是否发生变化),由于相同的元素,并不会交换位置,所以冒泡排序是稳定的。

7、冒泡排序的类比

        冒泡排序类似于:操场上的学生,老师叫他们先站成一排,然后自己从低到高站好,学生们会自己和相邻的同学比较,高的向后移,低的向前移,简单。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值