冒泡排序及其优化

        冒泡排序是一种很实用的排序方法,其主要思想是:在要排序的一组数中,对当前还未排好序的数,对从前往后对相邻的两个数依次进行比较和调整,让较大的数往后移(往下移),较小的数往前走(往上冒),即相当于每次找到一个最大值,并且相对于在后面,因此假如一组数有 n个数,只需要比较 n-1 次。例如一组数为 2,3,56,24,36,25,78,96,54。

第一次比较:2,3,24,36,25,56,78,54,96

第二次比较:2,3,24,25,36,56,54,78,96

第三次比较:2,3,24,25,36,54,56,78,96     //数据比较特殊,第三次就完成了

第四次比较:2,3,24,25,36,54,56,78,96  

第五次比较:2,3,24,25,36,54,56,78,96

第六次比较:2,3,24,25,36,54,56,78,96  

第七次比较:2,3,24,25,36,54,56,78,96  

第八次比较:2,3,24,25,36,54,56,78,96    

    实现代码:

    /**
     * O(n^2)    稳定
     * @param array
     */
    public static void sort(int[] array){
//        比较轮数
        for (int i = 0; i < array.length - 1; i++) {
            //有序的数字就是经过的轮数,相邻两两比较,-1操作防止越界
            for (int j = 0; j < array.length - i - 1; j++) {
                int temp = 0;
                if(array[j] > array[j+1]){
                    temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
                }
            }
        }
    }

 优化:  由上面分析可知,改代码在第三次已经达到了有序,但是用上面方法仍然会将剩下的轮数全部比较,因此可以优化上面代码:

   public static void sort(int[] array){
//        比较轮数
        for (int i = 0; i < array.length - 1; i++) {
            //每一轮的初始值为true,(如果最终仍为true,说明经过了一轮的比较,都么发生数据的交换,说明已经全部有序)
            boolean isSort = true;
            //有序的数字就是经过的轮数,相邻两两比较,-1操作防止越界
            for (int j = 0; j < array.length - i - 1; j++) {

                int temp = 0;
                if(array[j] > array[j+1]){
                    temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
//                    交换了说明无序,置为false,
                    isSort = false;
                }
            }
//        退出循环
            if (isSort){
                break;
            }
        }
    }

优化:若数据右半区已经有序了,但是左半区仍需要排序,但是根据冒泡的相邻两两比较,仍会对所有数据进行比较,其实只需要比较无序的左半区,可以用一个位置量来标记有序区,所以可以再次优化:

   public static void sort(int[] array){
        int sortLastIndex = 0;//标记最后一次交换的位置
        int sortIndex = array.length - 1;//有序区的起始位置,只需要比到这
//        比较轮数
        for (int i = 0; i < array.length - 1; i++) {
            //每一轮的初始值为true,无交换说明有序
            boolean isSort = true;
            for (int j = 0; j < sortIndex; j++) {
                int temp = 0;
                if(array[j] > array[j+1]){
                    temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
//                    交换了说明无序,置为false
                    isSort = false;
                    sortLastIndex = j + 1;
                }
            }
            sortIndex = sortLastIndex;
            if (isSort){
                break;
            }
        }
    }
原文地址:https://www.cnblogs.com/128-cdy/p/11002633.html