冒泡排序(分析+代码调优)

本文深入解析冒泡排序算法,包括其基本原理、代码实现及优化策略。通过对比优化前后的时间复杂度,展示了如何利用交换标志提升排序效率。同时,提供了大量数据测试结果,直观呈现算法性能。

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

冒泡排序

冒泡排序是一种比较简单的排序算法,其基本思想是:通过对待排序序列从前向后(从下标较小的元素开始),依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,可以形象的理解为像水底下的气泡一样逐渐向上冒,较大的数字沉底,较小的数字上浮。

算法描述

  • i从0开始,ii+1比较,如果i>i+1,那么就互换
  • i不断增加,直到i<n-1(n是数组元素的个数,n-1是数组已经最后一个元素) ,一趟下来,可以让数组元素中最大值排在数组的最后面

代码调试

从最简单开始,首先我们创建一个数组,该数组有3位数字:

 int [] arrays={3,2,1};

外层循环是排序的趟数
排序趟数只需要比较arrays.length - 1
第一趟排序结束后,第3位是最大的了

一趟  i=0 i<arrays.length-1 i++  
  比较 {3, 2, 1}
     比较第一次 (2 3) 1
        比较第二次 2 (1 3)

内层循环是当前趟数需要比较的次数
第二趟排序结束后,第2位是最大的了。

二趟  i=1 i<arrays.length-1 i++  
  比较 {2, 1, 3}
     比较第一次 (1 2) 3
     比较结束

图解

Java代码实现冒泡排序(优化前)

public class BUB {
    public static void main(String[] args) {
        int[] arrays = {3, 2, 1};
        System.out.println("排序前: " + Arrays.toString(arrays));
        //冒泡排序
        bubbleSort(arrays);
        System.out.println("排序后: " + Arrays.toString(arrays));

    }

    private static void bubbleSort(int[] arrays) {
// 每一趟排序,就是将最大的排序在最后
        //外层循环是排序的趟数 
        // arrays.length-1防止数组下标越界
        for (int i = 0; i < arrays.length-1; i++) {
            //内层循环是当前趟数需要比较的次数 
            // arrays.length-1-i 是为了减少比较的次数
            for (int j = 0; j < (arrays.length-1)- i; j++) {
                if (arrays[j] > arrays[j+1]) {
                   int temp = arrays[j];
                    arrays[j] = arrays[j+1];
                    arrays[j+1] = temp;
                }
            }

        }
    }
使用大量数据测试冒泡排序的时间
public class BUB {
    public static void main(String[] args) {
        int[] arrays = new int[80000];
        for (int i = 0; i < 80000; i++) {
            // 会生成[0,1000000)的数
            arrays[i] = (int)(Math.random() * 1000000);
        }
        Date date1 = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String datestr1 = simpleDateFormat.format(date1);
        System.out.println("排序前的时间是:"+datestr1);
        // 调用冒泡排序方法
        bubbleSort(arrays);
        Date date2 = new Date();
        String datestr2 = simpleDateFormat.format(date2);
        System.out.println("排序前的时间是:"+datestr2);}
排序前的时间是:2020-03-12 20:40:28
排序前的时间是:2020-03-12 20:40:39

最优算法

// 交换旗帜变量 = 假 (False)
// 从 i = 1 到 最后一个没有排序过元素的指数
// 如果 左边元素 > 右边元素
// 交换(左边元素,右边元素)
// 交换旗帜变量 = 真(True)
// while 交换旗帜变量

Java代码实现冒泡排序(优化后)

public static void bubbleSort(int[] arr) {
        // 每一趟排序,就是将最大的排序在最后
        int temp = 0; //临时变量
        boolean flag = false; // 标识变量,表示是否进行过交换
        for (int i = 0; i < arr.length - 1; i++) { // 外循环,一共循环数组长度-1次
            for (int j = 0; j < arr.length - 1 - i; j++) { // 内循环,每次只需要排序沉底元素之前的元素
                // 如果前面的数比后面的数大,则交换
                if (arr[j] > arr[j + 1]) {
                    flag = true;
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
            if (!flag) { // 在一趟排序中,一次交换都没有发生过
                break;
            } else {
                flag = false; // 重置flag,进行下次判断
            }
        }
    }
使用大量数据测试冒泡排序的时间

全部代码

public class BUB {
    public static void main(String[] args) {
   
       int[] arrays = {3,2,1};

        System.out.println("排序前: " + Arrays.toString(arrays));
        //冒泡排序
        bubbleSort(arrays);
        System.out.println("排序后: " + Arrays.toString(arrays));

    }
    public static void bubbleSort(int[] arr) {
        // 每一趟排序,就是将最大的排序在最后
        int temp = 0; //临时变量
        boolean flag = false; // 标识变量,表示是否进行过交换
        for (int i = 0; i < arr.length - 1; i++) { // 外循环,一共循环数组长度-1次
            for (int j = 0; j < arr.length - 1 - i; j++) { // 内循环,每次只需要排序沉底元素之前的元素
                // 如果前面的数比后面的数大,则交换
                if (arr[j] > arr[j + 1]) {
                    flag = true;
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
            if (!flag) { // 在一趟排序中,一次交换都没有发生过
                break;
            } else {
                flag = false; // 重置flag,进行下次判断
            }
        }
    }
}

时间复杂度

优化前:

  • 最优的时间复杂度:O(n^2) --------------------------> 此种情况下在排序的开始已经排好序
  • 最坏的时间复杂度:O(n^2) --------------------------> 此种情况下在排序的开始为逆序
  • 平均的时间复杂度:O(n^2)

存留

public class BUB {

    public static void main(String[] args) {

/*        Scanner sc = new Scanner(System.in);

        int[] arr = new int[3];//[sc.nextInt()];
        for (int i = 0; i < arr.length; i++) {

            arr[i] = sc.nextInt();
        }
        sc.close();*/

        int[] arr = {3,2,1};
        System.out.println("排序前:"+Arrays.toString(arr));
        bubbleSort(arr);
        System.out.println("排序后:"+Arrays.toString(arr));
    }


    public static void bubbleSort(int[] arr) {

        boolean flag = false;
    // 外循环,一共循环数组长度-1次
        for (int i = 0; i < arr.length; i++) {
            // 内循环,每次只需要排序沉底元素之前的元素
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    flag = true;
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }

            if (!flag) { // 在一趟排序中,一次交换都没有发生过
                break;
            } else {
                flag = false; // 重置flag,进行下次判断
            }

        }


    }
}
//通过字符串转化成数组 String[] s = sc.nextLine().split(" ");
// int num[]=new int[s.length];
// num[i]=Integer.parseInt(String.valueOf(s[i]));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值