java常见排序算法——冒泡排序

61 阅读2分钟

首先说明一下,此案例中的排序是基于数组升序排列。

原理:每次比较两个相邻的元素,将较大的元素交换至右端。

思路:

  1. 从头部开始比较相邻的两个元素,如果头部的元素比后面的大,就交换两个元素的位置;
  2. 往后对每个相邻的元素都做这样的比较、交换操作,这样到数组尾部时,最后一个元素会成为最大的元素;
  3. 重新从头部开始第 1、2 步的操作,除了在这之前尾部已经排好的元素;
  4. 继续对越来越少的数据进行比较、交换操作,直到没有可比较的数据为止,排序完成。

下面用代码实现一下:

   public static void main(String[] args) {
        // 定义数组长度
        int arrLength = 10;
        // 声明一个数组
        int[] arr = new int[arrLength];
        // 初始化数组
        Random rand = new Random();
        for (int i = 0; i < arr.length; i++) {
            arr[i] = rand.nextInt(50);
        }
        System.out.println("排序前数组: " + Arrays.toString(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;
                }
            }
        }
        System.out.println("排序后数组: " + Arrays.toString(arr));
    }

运行结果:

排序前数组: [47, 3, 16, 35, 38, 1, 32, 47, 20, 24]
排序后数组: [1, 3, 16, 20, 24, 32, 35, 38, 47, 47]

可以看到,上面的代码已经成功实现冒泡排序了,但是这是最优的写法吗?想一下,如果这个数组本来就是有序的呢,或者通过前几次排序就已经有序了呢,按理说,这时只需一次或几次排序就可以知道数组是有序的了,如果按照上面的方法进行排序,很明显,后面的循环比较是毫无意义的,凭着这个思路,优化一下代码:

public static void main(String[] args) {
        // 定义数组长度
        int arrLength = 10;
        // 声明一个数组
        int[] arr = new int[arrLength];
        // 初始化数组
        Random rand = new Random();
        for (int i = 0; i < arr.length; i++) {
            arr[i] = rand.nextInt(50);
        }
        System.out.println("排序前数组: " + Arrays.toString(arr));

        // 进行冒泡排序
        for (int i = 0; i < arr.length - 1; i++) {
            boolean switchFlag = false; // 增加布尔变量,记录本次循环是否存在相邻元素的交换
            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;
                    switchFlag = true;
                }
            }
            if (!switchFlag) {// 如果本次循环不存在相邻元素交换,说明数组已经有序了
                break;
            }
        }
        System.out.println("排序后数组: " + Arrays.toString(arr));
    }

冒泡排序最好的时间复杂度为O(n),最坏情况下时间复杂度为O(n^2^),平均时间复杂度为O(n^2^) 。