bubble sort(冒泡排序)

该博客详细介绍了冒泡排序的四种优化方法,包括添加标志位以提前结束排序、记录有序标记、鸡尾酒排序以及结合鸡尾酒排序和有序标记的优化。通过这些优化,可以提高冒泡排序的效率,减少不必要的比较和交换操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

依次对比,大值朝后,每次至少可确定一个当前循环最大值放入最后

public static int[] Bubble_Sort(int[] sourceArray){
        if(sourceArray==null || sourceArray.length<2) return sourceArray;
        //对原数据进行拷贝
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
        for (int i = 1; i < arr.length; i++) {  //需要遍历 length-1 次
            for(int j=0; j< arr.length-i;j++){  //根据循环次数,每次循环比较次数减1,
                if(arr[j]>arr[j+1]){//如果前面的值大于前面的值要置换位置,
                    // 这样当相等时不交换位置保证了稳定性
                    // 这样可将"最大值"放入本次循环的最后位置
                    int temporary=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temporary;
                }
            }
        }
        return arr;
    }

优化 1/4 加入一个标志位优化一下 

 public int[] Bubble_Sort_MAX(int[] sourceArray){
        if(sourceArray==null || sourceArray.length<2) return sourceArray;
        //对原数据进行拷贝
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
        for (int i = 1; i < arr.length; i++) {//从第i+1个数向后依次遍历
            boolean flag=true;//加入标志位等于 true 表示现在没有 进行换位操作
            for(int j=0; j< arr.length-i;j++){
                if(arr[j]>arr[j+1]){//如果前面的值大于前面的值要置换位置
                    //这样当相等时不交换位置保证了稳定性
                    // 这样可将"最大值"放入本次循环的最后位置
                    int temporary=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temporary;
                    flag=false;//若在本次循环中进行了换位操作则 设为 false
                }
            }
            if(flag) return arr; //若在某次循环中没有发生依次换位,则说明数组已经有序
        }
        return arr;
    }

优化 2/4 记录有序标记

public int[] Bubble_Sort_MAX2(int[] sourceArray){
        if(sourceArray==null || sourceArray.length<2) return sourceArray;
        //对原数据进行拷贝
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
        int rightMark= arr.length-1;
        boolean swopFlag=true;//加入标志位等于 true 表示现在没有 进行换位操作
        int temporaryRightMark=0;
        for (int i = 1; i < arr.length; i++) {//从第一个数开始
            for (int j = 0; j < rightMark; j++) {
                if(arr[j]>arr[j+1]){//如果前面的值大于前面的值要置换位置
                    //这样当相等时不交换位置保证了稳定性
                    // 这样可将"最大值"放入本次循环的最后位置
                    int temporary=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temporary;
                    swopFlag=false;//若在本次循环中进行了换位操作则 设为 false
                    temporaryRightMark=j; //下次循环的结束位置,临时的后面可能继续改变
                }
            }
            if(swopFlag) return arr; //若在某次循环中没有发生依次换位,则说明数组已经有序
            rightMark=temporaryRightMark;//在下次循环前将循环的结束位置 赋值
            swopFlag=true;//每次循环结束前将下次是否循环的标志重置
        }
        return arr;
    }

优化 3/4 鸡尾酒排序

在没此循环中找到一个最大数和一个最小数,从而只需要循环一半次数 即可将数据排好

这里有一个问题,就是每次排两个那么奇数的时候怎么办呢?

解释:每次排序两个最后剩下的一个刚好是最中间的; 

注意一点,在写下面第二次循环的时候别 交换变量时,复制第一次的循环会出错,别问我怎么知道的!!!!

public static int[] Bubble_Sort_MAX3(int[] sourceArray){
        if(sourceArray==null || sourceArray.length<2) return sourceArray;
        //对原数据进行拷贝
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
        boolean swopFlag=true;
        for (int i = 0; i < arr.length/2; i++) {//从第一个数开始
            for (int j = 0; j < arr.length-i-1; j++) {
                if(arr[j]>arr[j+1]){//如果前面的值大于前面的值要置换位置
                    //这样当相等时不交换位置保证了稳定性
                    // 这样可将"最大值"放入本次循环的最后位置
                    int temporary=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temporary;
                    swopFlag=false;//若在本次循环中进行了换位操作则 设为 false
                }
            }
            if(swopFlag) return arr; //若在某次循环中没有换位,则说明数组已经有序
            // ----------------------------------------------------------------------
            swopFlag=true;//进入前将换位标记重置
            for (int j = arr.length-i-1; j >i; j--) {
                if(arr[j]<arr[j-1]){//如果后面的值小于前面的值要置换位置
                    //这样当相等时不交换位置保证了稳定性
                    // 这样可将"最小值"放入本次循环的最前位置
                    int temporary=arr[j]; arr[j]=arr[j-1]; arr[j-1]=temporary;
                    swopFlag=false;//若在本次循环中进行了换位操作则 设为 false
                }
            }
            if(swopFlag) return arr; //若在某次循环中没有换位,则说明数组已经有序
            swopFlag=true;//每次循环结束前将下次是否循环的标志重置
        }
        return arr;
    }

优化 4/4 结合鸡尾酒和有序标记

思路: 要比较的数组是中间非最大和最小的,用标记位标记两边已经有序数组,比较中间无序数组

晚上懒得写注释了,中间出错,重写了一波,蛋疼!

public static int[] Bubble_Sort_MAX4(int[] sourceArray){
        if(sourceArray==null || sourceArray.length<2) return sourceArray;
        //对原数据进行拷贝
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
        int left=0;
        int right=arr.length-1;
        boolean flag=true;
        int temporary;
        int temporaryZ = 0;
        for (int i = 0; i < arr.length/2; i++) {
            for(int j=left; j<right;j++){
                if(arr[j]>arr[j+1]){
                    temporary=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temporary;
                    flag=false;  temporaryZ=j;
                }
            }
            if (flag==true) return arr;
            right=temporaryZ;
            flag=true;
            for (int j=right;j>left;j--){
                if (arr[j]<arr[j-1]){
                    temporary=arr[j]; arr[j]=arr[j-1]; arr[j-1]=temporary;
                    flag=false;temporaryZ=j;
                }
            }
            if (flag==true)return arr;
            left=temporaryZ;
            flag=true;
        }
        return arr;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值