关于冒泡排序

知道冒泡排序,但是不知道冒泡还可以优化。

第一种冒泡

举个栗子: 一组数 :3 2 5 4 6 1 8 9 7 ,将这组数从左到右从小到大排列,冒泡排序就是用相邻的两个数去比较,如果后一个数比前一个数大就交换两个数的位置,以此类推。。。

                                                                          为交换前 :    3 2 5 4 6 1 8 9 7

本组数 3 和 2 先比较,3 比2 大,交换位置,交换后数组为:2 3 5 4 6 1 8 9 7

然后 3 和 5 比较,3 比 5小,所以不交换位置:                      2 3 5 4 6 1 8 9 7

接着 5 和 4 比较,5 比 4 大,交换位置:                                2 3 4 5 6 1 8 9 7

6 和 1 比较,交换位置:                                                          2 3 4 5 1 6 8 9 7

6 和8 比较,不交换位置:                                                       2 3 4 5 1 6 8 9 7

8 和9 比较,不交换位置:                                                       2 3 4 5 1 6 8 9 7

9 和 7 比较,交换位置:                                                          2 3 4 5 1 6 8 7 9

至此经过冒泡第一轮排序结束,未排序前整个数组是无序的,经过第一轮排序就产生了无序区和有序去,其中 9 的位置是有序区,9 左面数字所在的是无序区。然后依照第一轮的方法再接着比较:

                                     无序区                有序区

第二轮排序后:         2 3 4 1 5 6 7            8 9

第三轮排序后:         2 3 1 4 5 6               7 8 9

第四轮排序后:         2 1 3 4 5                  6 7 8 9

第五轮排序后:         1 2 3 4                     5 6 7 8 9(到此轮已经是全部是有序的了)

第六轮排序后:         1 2 3                        4 5 6 7 8 9 

第七轮排序后:         1 2                           3 4 5 6 7 8 9 

第八轮排序后:         1                              2 3 4 5 6 7 8 9 

第九轮排序后:                                         1 2 3 4 5 6 7 8 9

到此冒泡排序全部完成。代码如下:

  int[] num = {3,2,5,4,6,1,8,9,7};
         //共进行 数组长度 轮
        for (int i = 0; i < num.length; i++){
            //每一轮进行 数组长度-1 次比较
            for (int j = 0; j < num.length - 1; j++){
                //交换位置
                if (num[j] > num[j+1]){

                    int temp = num[j];

                    num[j] = num[j+1];

                    num[j+1] = temp;
                }
            }
        }

可以发现,在第五轮的时候数组已经完全排好序了,然鹅程序并没有执行完,不能停啊~以至于第六轮、第七、八、九轮完全在做无用功,这也说明了冒泡还可以优化空间----就是判断程序没有执行完,数组已经有序的情况的点在哪里,这时发现数组在已经完全有序的情况下不在进行位置的交换,可以用这种情况作为一个标志点,一旦出现一整轮下来都没有数交换位置的情况,就立即跳出循环停止运行:

第二种冒泡 

  int[] num = {3,2,5,4,6,1,8,9,7};
             //共进行 数组长度 轮
        for (int i = 0; i < num.length; i++){
            boolean flag = true;
            //每一轮进行 数组长度 - 1 次比较
            for (int j = 0; j < num.length - 1; j++){
                //交换位置
                if (num[j] > num[j+1]){

                    int temp = num[j];

                    num[j] = num[j+1];

                    num[j+1] = temp;

                    flag = false;//如果发生交换位置的情况,就代表还没完全有序
                }
            }
            if (flag) {
                break;//如果flag为true则表示没有发生位置交换,跳出循环
            }
        }

既然能优化第一次,也就可能优化第二次,全部有序可以判断,那么部分有序呢?像本例的第二轮从第五位也就是下标为4的数开始到最后已经是有序的了,也就是说下一轮排序这个区间的数都不用再继续比较了,所以,这个判断的点就是判断再哪个位置之后就部在发生位置的交换:

第三种冒泡 

 int[] num = {3,2,5,4,6,1,8,9,7};
        // 停止位置标记
        int index = num.length - 1;
        //最后一次交换的位置
        int indexLast = 0;
        for (int i = 0; i < num.length; i++){
            boolean flag = true;
            for (int j = 0; j < index ; j++){
                //交换位置
                if (num[j] > num[j+1]){
                    int temp = num[j];
                    num[j] = num[j+1];
                    num[j+1] = temp;
                    flag = false;
                    indexLast = j; //记录最后一次交换的位置
                }
            }
            index = indexLast;
            if (flag) {
                break;//如果flag为true则表示没有发生位置交换,跳出循环
            }
        }

还有很多更强大的排序算法。。。一个一个来!~哈哈哈哈

猜你喜欢

转载自blog.csdn.net/qq_33417486/article/details/81157259