给自己五分钟,彻底搞懂并优化冒泡排序

Posted DayFight_DayUp

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了给自己五分钟,彻底搞懂并优化冒泡排序相关的知识,希望对你有一定的参考价值。

给自己五分钟,彻底搞懂并优化冒泡排序

冒泡排序思想

给定一个无序数组,让“重”的元素下沉,轻的元素上浮”,这个就是冒泡排序。

算法描述

1. 对于给定长度为N的数组, 我们从头进行N次扫描。
2. 每一次扫描相邻的两个元素进行大小比较,若某一元素大于它的下一个元素,就进行交换。
3. 每一次扫描都会把剩余元素的最大值下沉到剩余元素的末尾。故每扫描一次,下一次扫描的超度相应的就减一。

示例

假设要对 下面数组进行排序:

5, 4, 12, 11, 19, 2, 1, 14

第 1 趟扫描排序: 4 和 5 交换,12 和 11 交换, 19 下沉到数组末尾。

4, 5, 11, 12, 2, 1, 14, 19

第 2 趟扫描排序: 12 下沉到剩余元素末尾

4, 5, 11, 2, 1, 12, 14, 19

第 3 趟扫描排序: 11 下沉到剩余元素末尾

4, 5, 2, 1, 11, 12, 14, 19

第 4 趟扫描排序: 5 下沉到剩余元素末尾

4, 2, 1, 5, 11, 12, 14, 19

第 5 趟扫描排序: 4 下沉到剩余元素末尾
2, 1, 4, 5, 11, 12, 14, 19

第 6 趟扫描排序: 2 下沉到剩余元素末尾
1, 2, 4, 5, 11, 12, 14, 19

第 7 趟扫描排序: 空扫描,并没有元素交换
1, 2, 4, 5, 11, 12, 14, 19

冒泡排序的Java代码实现

	public static void bubbleSort(int[] arr) 
        int temp;
        for (int i = 0; i < arr.length - 1; i++) 
            for (int j = 0; j < arr.length - 1 - i; j++) 
                if (arr[j + 1] < arr[j]) 
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                
            
        
    

冒泡排序的第一次优化

冒泡排序弊端

从上面的结果中我们能看出。
上面的算法实现有弊端,假设我给定一个有序数组进行冒泡排序,这个算法还是会给我排序 N -1趟,每一趟都进行空扫描。
那么有木有方法让元素已经排序好了,没有交换就不进行扫描,直接结束排序呢?
有的。只要在上面算法中动一点小手脚就好。
关键点:只要没有发生元素交换。就直接结束循环扫描。

冒泡排序第一版优化

	/**
     * 冒泡排序优化 1
     * @param arr 数组
     */
    public static void bubbleSortPro1(int[] arr) 
        int temp;
        // 记录每一趟排序是不是有元素交换
        boolean hasChange;
        for (int i = 0; i < arr.length - 1; i++) 
            hasChange = false;
            for (int j = 0; j < arr.length - 1 - i; j++) 
                if (arr[j + 1] < arr[j]) 
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                    // 如果有元素交换就记录下来
                    hasChange = true;
                
            
            // 只要某一趟排序完了没有元素交换,那么就结束。
            if (!hasChange) 
                break;
            
        
    

冒泡排序第二次优化

假设有下面一个数组
3, 4, 2, 1, 5, 6, 7, 8
第一次扫描:
3 ,2, 1, 4, 5, 6, 7, 8
第二次扫描:
2 ,1, 3, 4, 5, 6, 7, 8
第三次扫描:
1, 2, 3, 4, 5, 6, 7, 8
有木有发现一个问题,其实未排序的5,6,7,8(右侧已经有序),但是就算通过第二版优化,减少了扫描次数,那么每一套扫面描还是会让相邻的两个元素进行比较。
那么优化方案是啥:
关键点:记住最后一次交换的位置。下一次扫描只比较到这个位置。往后的元素不再比较。

冒泡排序第二版优化

	/**
     * 冒泡排序优化版2
     *
     * @param arr 数组
     */
    public static void bubbleSortPro2(int[] arr) 
        int tmp;
        boolean haschange;
        int sortBorder = arr.length - 1;
        int lastChangeIndex = 0;
        for (int i = 0; i < arr.length - 1; i++) 
            haschange = false;
            for (int j = 0; j < sortBorder; j++) 
                if (arr[j] > arr[j + 1]) 
                    tmp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = tmp;
                    haschange = true;
                    lastChangeIndex = j;
                
            
            sortBorder = lastChangeIndex;
            if (!haschange) 
                break;
            
        
    

以上是关于给自己五分钟,彻底搞懂并优化冒泡排序的主要内容,如果未能解决你的问题,请参考以下文章

给自己五分钟,彻底搞懂并优化冒泡排序

五分钟搞懂Vuex

五分钟搞懂Vuex

如何给面试官写一个满意的冒泡排序

java基础(16)数组的高级应用--冒泡排序选择排序

卧槽!冒泡排序有这么难???