排序算法O(n^2)系列之冒泡排序

138 阅读2分钟

这是我参与更文挑战的第15天,活动详情查看: 更文挑战

冒泡排序

“冒泡排序法除了它迷人的名字和导致了某些有趣的理论问题这一事实外,似乎没有什么值得推荐的。” ———— Donald E. Knuth(1974 年图灵奖获得者)

bubbleSort.gif

1. 基本实现


public static void main(String[] args) {
    int[] arr = new int[]{189, -6, 0, 1, 34, 78};
    bubbleSort2(arr);
    Arrays.stream(arr).forEach(System.out::println);
}

public static void bubbleSort2(int[] arr) {
    int count=0;
    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]) {
                swap(arr, j, j + 1);
            }
            count++;
        }
    }
    System.out.println("循环进行了 "+ count +" 次");
}

public static void swap(int[] arr, int i, int j) {
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}


//output
循环进行了 15 次
-6
0
1
34
78
189

Process finished with exit code 0

2. 优化版本1

在循环遍历过程中记录了是否排过序的状态。如果某一批次中已经开始不进行排序了。就证明从头元素开始的那串剩下数组元素已经是排序正确的了。


public static void main(String[] args) {
    int[] arr = new int[]{189, -6, 0, 1, 34, 78};
    bubbleSort2(arr);
    Arrays.stream(arr).forEach(System.out::println);
}

public static void bubbleSort2(int[] arr) {
    Boolean swaped = true;
    for (int i = 0; i < arr.length - 1; i++) {
        if (!swaped) {
            break;
        }
        swaped = false;
        for (int j = 0; j < arr.length - 1 - i; j++) {
            if (arr[j] > arr[j + 1]) {
                swap(arr, j, j + 1);
                swaped = true;
            }
        }
    }
}

public static void swap(int[] arr, int i, int j) {
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

//output
循环进行了 9 次
-6
0
1
34
78
189

Process finished with exit code 0

3. 优化版本2

此版本在优化版本1的基础上,再做一层优化,多引入一个变量,专门记录最后一个进行过交换的数组元素的位置。这个优化的作用是在没轮次的循环中尽可能的减少比较交换的次数。如果在某个位置之后的元素两两比较,但都没有产生过元素交换动作,那就证明从这个位置之后的元素都是有序的了。

public static void main(String[] args) {
    int[] arr = new int[]{189, -6, 0, 1, 34, 78};
    bubbleSort2(arr);
    Arrays.stream(arr).forEach(System.out::println);
}

public static void bubbleSort2(int[] arr) {
    int count = 0;
    boolean swapped = true;
    int length = arr.length, lastSwappedIndex = length - 1;
    while (swapped) {
        swapped = false;
        int tempLastUpdateIndex = 0;
        for (int i = 0; i < lastSwappedIndex; i++) {
            if (arr[i] > arr[i + 1]) {
                swap(arr, i, i + 1);
                swapped = true;
                tempLastUpdateIndex = i;
            }
            count++;
        }
        lastSwappedIndex = tempLastUpdateIndex;
    }
    System.out.println("循环进行了 " + count + " 次");
}

public static void swap(int[] arr, int i, int j) {
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

//output
循环进行了 9 次
-6
0
1
34
78
189

Process finished with exit code 0

声明:此文中的图引自网络。