冒泡排序

161 阅读1分钟

1.思路:冒泡排序只会操作相邻的两个数据。每次冒泡排序都会对相邻的两个元素进行比较,看是否满足大小关系要求。如果不满足就让它俩交换。

2.图解:对数组[4, 5, 6, 3, 2, 1]进行冒泡排序,每次冒泡操作的详细过程如下图所示: image.png

从图中可以看出只需要array.length-1次冒泡,数组就可以排列好。

3.代码实现

public void bubbleSort(int[] arr) {
        // 需要先判断数组是否为空,若不判断,数组为空时arr.length会报空指针异常
        if (arr == null || arr.length < 2) {
            return;
        }
        
        // 需要进行arr.length - 1次冒泡
        for (int i = 0; i < arr.length - 1; i++) {
            // 每进行一次冒泡,下一次冒泡需要操作的元素数量减一
            for (int j = 0; j < arr.length - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }

如果数组在arr.length - 1次冒泡之前已经排列好,则不需要在进行冒泡排序。我们可以根据这个特点进行优化。

优化后的冒泡排序

public void bubbleSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
       
        boolean flag = true;  // 判断在一次冒泡中是否一次交换也没有发生
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = 0; j < arr.length - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                    flag = false;  // 发生了交换,将flag设为false
                }
            }
           // 一次冒泡中若一次交换都没有发生,则排序已经完成,可提前结束冒泡排序
            if (flag)  return;  
        }
    }

4.性质: ①时间复杂度:O(n^2)     ②空间复杂度:O(1)     ③稳定排序     ④原地排序
*稳定排序:如果原数组中,a和b的值相同,a在b的前面,排序结束后a仍在b的前面,则为稳定排序。
*原地排序:在排序过程中没有申请多余的空间。