Java常用算法 - 冒泡排序

122 阅读3分钟

冒泡排序

冒泡排序(Bubble Sort)是一种简单的交换排序算法,通过重复地走访过要排序的元素,依次比较两个相邻的元素,如果顺序错误则进行交换。

原理

  1. 比较相邻的元素,如果第1个比第2个大,则进行交换。
  2. 对每一对相邻的元素做同样的工作,从最开始第一对到最后一对,最后的元素将会是最大的值。
  3. 针对所有的元素重复以上的步骤,除了最后1个(已经是最大的值)。
  4. 持续每次对越来越少的元素重复上述步骤,直到没有任何一对数字需要比较。

图解分析

假设当前存在数组{67,2,23,12,34},需要对其进行冒泡排序,步骤如下所示:

PS:箭头标记操作是将两个元素进行比较,若第1个元素比第2个元素大,则进行交换。

bubbleSortStep1.jpg bubbleSortStep2.jpg bubbleSortStep3.jpg bubbleSortStep4.jpg

代码实现

public static void bubbleSort(int[] arr) {
    int length = arr.length;

    for (int i = 0; i < length - 1; i++) {
        for (int j = 0; j < length - 1 - i; j++) {
            if (arr[j] > arr[j + 1]) {
                int temp = arr[j + 1];
                arr[j + 1] = arr[j];
                arr[j] = temp;
            }
        }
        System.out.print("\n第" + (i + 1) + "轮排序结果: ");
        for (int item : arr) {
            System.out.print(item + " ");
        }
    }
}
public static void main(String[] args) {
    int[] arr = new int[]{67, 2, 23, 12, 34};
    bubbleSort(arr);
}
/* 
结果打印:
第1轮排序结果: 2 23 12 34 67 
第2轮排序结果: 2 12 23 34 67 
第3轮排序结果: 2 12 23 34 67 
第4轮排序结果: 2 12 23 34 67 
*/

时间复杂度

最坏情况

逆顺序排列,假设有n个数,等差数列: 1+2+3+4+...+n,此时时间复杂度为:O(n^2)。

最好情况

顺序排列,但对于冒泡排序来说,即使有序仍然会对每个元素进行冒泡,此时时间复杂度仍为:O(n^2)。

算法优化

由上述图解过程,不难看出,在第3轮遍历时,不存在元素交换的情况,此时数组已经是有序的,这种情况就没必要再继续冒泡下去,因此需要对程序进行优化。

优化思路

定义1个交换标识flag,赋值为false,若经历一轮冒泡,有交换元素,则为true;若没有交换元素,则为false;最后通过交换标识的值,判断是否需要进行下一轮冒泡。

代码示例

public static void bubbleSortOptimize(int[] arr) {
    int length = arr.length;
    boolean flag = false; // 交换标识

    for (int i = 0; i < length - 1; i++) {
        flag = false; // 重置交换标识
        for (int j = 0; j < length - 1 - i; j++) {
            if (arr[j] > arr[j + 1]) {
                int temp = arr[j + 1];
                arr[j + 1] = arr[j];
                arr[j] = temp;
                flag = true;
            }
        }
        System.out.print("\n第" + (i + 1) + "轮排序结果: ");
        for (int item : arr) {
            System.out.print(item + " ");
        }
        if (!flag) break;
    }
}
public static void main(String[] args) {
    int[] arr = new int[]{67, 2, 23, 12, 34};
    bubbleSortOptimize(arr);
}
/*
结果打印:
第1轮排序结果: 2 23 12 34 67 
第2轮排序结果: 2 12 23 34 67 
第3轮排序结果: 2 12 23 34 67 
*/

时间复杂度

最坏情况

最坏情况仍是逆顺序排列,时间复杂度为:O(n^2)。

最好情况

顺序排列,由于在第一轮冒泡过程中,交换标识flag为false,不需要进行后续的冒泡,因此时间复杂度为:O(n)。

参考文献

Java八大常用算法

冒泡排序优化