冒泡排序

冒泡排序的原理(此处解释针对由小到大排序):
对于一个长度为n的数组来说,冒泡排序由两个指针(i,i+1),分别指向数组的第一个元素和第二个元素;
遍历数组元素,每次遍历都会比较两个元素的大小,如果第i个元素比第i+1个元素大,则交换两个元素的值。
同时指针后移,重复上述操作,并选出最大的元素至于数组的最后一位。
第一轮遍历结束后会发现数组的第n-1个元素是最大值,接下来进行遍历的轮数无需管最后一个元素(因为他已经是最大值)。
意味着每遍历一轮就会确定一个最大值(遍历第一轮确定最后一位最大值(第n-1位),遍历第二轮确定第n-2位最大值)。
以此类推,第一轮遍历数组n-1个元素,第二轮遍历数组n-2个元素,最后一轮只需要遍历两个元素。
接下来定义一个长度为7的数组:
int[] arr = {3, 1, 5, -6, 2, 10, -8};
然后通过代码演示冒泡排序的推演流程:

点击查看代码
private static void sortByBubbleTwo(int[] arr) {
        //第一轮排序的结果
        for (int i=0;i<arr.length-1;i++){
            int temp=0;
            if (arr[i] > arr[i + 1]) {
                temp = arr[i];
                arr[i] = arr[i + 1];
                arr[i + 1] = temp;
            }
        }
        System.out.println("第一轮排序后的结果arr[]:"+Arrays.toString(arr));
        //第二论排序的结果
        for (int i=0;i<arr.length-2;i++){
            int temp=0;
            if (arr[i] > arr[i + 1]) {
                temp = arr[i];
                arr[i] = arr[i + 1];
                arr[i + 1] = temp;
            }
        }
        System.out.println("第二轮排序后的结果arr[]:"+Arrays.toString(arr));
        //第三轮排序的结果
        for (int i=0;i<arr.length-3;i++){
            int temp=0;
            if (arr[i] > arr[i + 1]) {
                temp = arr[i];
                arr[i] = arr[i + 1];
                arr[i + 1] = temp;
            }
        }
        System.out.println("第三轮排序后的结果arr[]:"+Arrays.toString(arr));
        //第四轮排序的结果
        for (int i=0;i<arr.length-4;i++){
            int temp=0;
            if (arr[i] > arr[i + 1]) {
                temp = arr[i];
                arr[i] = arr[i + 1];
                arr[i + 1] = temp;
            }
        }
        System.out.println("第四轮排序后的结果arr[]:"+Arrays.toString(arr));
        //第五轮排序的结果
        for (int i=0;i<arr.length-5;i++){
            int temp=0;
            if (arr[i] > arr[i + 1]) {
                temp = arr[i];
                arr[i] = arr[i + 1];
                arr[i + 1] = temp;
            }
        }
        System.out.println("第五轮排序后的结果arr[]:"+Arrays.toString(arr));
        //第六轮排序的结果
        for (int i=0;i<arr.length-6;i++){
            int temp=0;
            if (arr[i] > arr[i + 1]) {
                temp = arr[i];
                arr[i] = arr[i + 1];
                arr[i + 1] = temp;
            }
        }
        System.out.println("第六轮排序后的结果arr[]:"+Arrays.toString(arr));
    }

接下来查看控制条输出结果:
第一轮排序后的结果arr[]:[1, 3, -6, 2, 5, -8, 10]
第二轮排序后的结果arr[]:[1, -6, 2, 3, -8, 5, 10]
第三轮排序后的结果arr[]:[-6, 1, 2, -8, 3, 5, 10]
第四轮排序后的结果arr[]:[-6, 1, -8, 2, 3, 5, 10]
第五轮排序后的结果arr[]:[-6, -8, 1, 2, 3, 5, 10]
第六轮排序后的结果arr[]:[-8, -6, 1, 2, 3, 5, 10]
可以看出对一个长度为7的数组进行冒泡排序,一共进行了6(7-1)轮遍历,每一轮都会少遍历一个元素。第一轮减0,第二轮减1,第六轮减5;
最终可以将上述的推演过程改进为两个嵌套for循环
外层循环为:for (int n = 0; n <arr.length-1 ; n++);
内层循环为:for (int i = 0; i < arr.length - 1 - n; i++);
所以改进后的冒泡排序方法为:

点击查看代码
    private static void sortByBubble(int[]arr) {
        int temp=0;
        for (int n = 0; n <arr.length-1 ; n++) {
            for (int i = 0; i < arr.length - 1 - n; i++) {
                if (arr[i] > arr[i + 1]) {
                    temp = arr[i];
                    arr[i] = arr[i + 1];
                    arr[i+1]=temp;
                }
            }
            System.out.println("第"+n+"轮排序的结果arr:"+Arrays.toString(arr));
        }
    }

经过测试我们会发现存在内循环的遍历中会出现无元素交换顺序的情况,意味着无需进行此次循环进行排序,所以我们对此冒泡排序的方法进行优化
代码如下

点击查看代码
private static void sortByBubble(int[] arr) {
        int temp=0;
        boolean flag=true;
        //数组一共有n个元素,会遍历n-1轮,第一轮开始减一,每过一轮多减一;
        for (int n = 0; n < arr.length-1; n++) {
            for (int i = 0; i < arr.length-1 - n; i++) {
                if (arr[i] > arr[i + 1]) {
                    flag=false;
                    temp = arr[i];
                    arr[i] = arr[i + 1];
                    arr[i + 1]=temp;
                }
            }
            //优化:如果flag的值没有变化,代表没有元素位置发生改变,则跳出当前内循环
            if (flag) {
                break;
            }else{
                flag=true;
            }
            System.out.println("排序第"+n+"轮的数组为:arr[]:"+Arrays.toString(arr));

        }
posted @ 2022-09-11 15:35  与否业务NOW  阅读(32)  评论(0)    收藏  举报