• 冒泡排序及其优化


            冒泡排序是一种很实用的排序方法,其主要思想是:在要排序的一组数中,对当前还未排好序的数,对从前往后对相邻的两个数依次进行比较和调整,让较大的数往后移(往下移),较小的数往前走(往上冒),即相当于每次找到一个最大值,并且相对于在后面,因此假如一组数有 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;
                }
            }
        }
  • 相关阅读:
    综合实例-文本框类部件
    输入掩码
    WebP,Jpeg,Png格式图片的编解码区别
    美团点评提前批面经
    Android中AIDL的使用详解,如何发起回调?
    JNI在Android中的实践NDK:Hello World
    Timer实现原理
    百度秋招凉经:客户端测开
    阿里秋招面经:Android客户端开发工程师
    Picasso和Glide区别
  • 原文地址:https://www.cnblogs.com/128-cdy/p/11002633.html
Copyright © 2020-2023  润新知