Java实现冒泡排序

冒泡排序是一种不断交换相邻的元素的排序,一些元素在不断得被交换中,就像水中冒泡一样,因此得名冒泡排序。

算法原理

1.比较相邻的元素,如果前面元素比后面元素要小,那么则交换这两个元素。
2.对每一组相邻的元素都进行比较,从开始的第一对元素到结尾的最后一对元素依次进行比较,叫做一次冒泡。经过一次冒泡后,能保证最大的元素在最后
3.如果说数组有n个元素,进行1次冒泡后能保证最后1个元素是最大的,也就是说进行1次冒泡能保证排完最后1个元素。那么进行n-1次冒泡后,能保证排完n-1个元素,n-1个元素排序完成,那么整个数组排序完成。因此一共需要冒泡n-1次。
插入一张黑马的图

代码

public class Bubble {
    //交换a数组中索引x和索引y处的元素
    private static void exch(Comparable[]a,int x,int y){
        Comparable temp=a[x];
        a[x]=a[y];
        a[y]=temp;
    }
    //判断a元素是否小于b元素
    private static boolean less(Comparable a,Comparable b){
        return a.compareTo(b)<0;
    }
    public static void sort(Comparable[]a){
        final int N=a.length;
        //进行n-1次冒泡
        for(int i=N-1;i>0;i--){
        	
            for(int j=0;j<i;j++){
                if(less(a[j+1],a[j]))exch(a,j,j+1);
            }
        }
    }

    public static void main(String[] args) {
        Integer[]a=new Integer[50];
        for (int i = 0; i < a.length; i++) {
            a[i]=(int)(Math.random()*50);
        }
        System.out.println("排序前");
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]+" ");
        }
        System.out.println();
        System.out.println("排序后");
        sort(a);
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]+" ");
        }
    }
}

复杂度分析

  • 时间复杂度:共进行n-1次冒泡,第一次比较n-1次,第二次比较n-2次,第n-1次比较1次。1+2+3…+n-1=n(n-1)/2,因此时间复杂度为O(n^2)
  • 空间复杂度:只用到一个temp变量,空间复杂度为O(1)

冒泡排序的优化

mark:今天是2022年1月12日,在一次面试中突然被问到了冒泡排序该如何优化!打开这篇帖子看一下,我学java已经快两年了,不知不觉变秃了却没变强,继续努力!

第一种优化思路

假如在第一次冒泡后数组已经完全有序,按照冒泡排序的算法还会继续冒泡,此时其实没有必要。可以用一个boolean类型的变量标记此次排序中是否有交换元素,初始为false。当有交换元素后把变量标记为true,如果经过一轮冒泡后,变量还是false,name说明当前数组已经有序了。直接break跳出循环结束。
(PS:面试里我说的每轮冒泡后在检查一次看看是不是有序的,面试官不太满意。其实在冒泡的时候就已经比较了一轮了,完全可以像上面那样写。)

public void bubbleSort(int[]nums){
        if(nums==null|| nums.length<2)return ;
        int n=nums.length;
        
        for (int i = n-1; i >=0 ; i--) {
            for (int j = 0; j <i; j++) {
                boolean exch=false;
                if(nums[j]>nums[j+1]){
                    exch=true;
                    int temp=nums[j];
                    nums[j]=nums[j+1];
                    nums[j+1]=temp;
                }
                //这一趟冒泡没有交换元素,说明数组已经有序
                if(!exch)break;
            }
        }
    }

第二种优化思路

针对向[5,4,3,2,1,6,7,8,9,10]这种后半段有序而前半段无序的数组,冒泡的交换主要在前面,我们可以标记下每次冒泡中最后交换元素的索引位置,那么在这个索引位置后面的元素都已经全部有序,便不用继续排序

public void bubbleSort(int[]nums){
        if(nums==null|| nums.length<2)return ;
        int n=nums.length;
        int k=n-1;

        for (int i = n-1; i >=0 ; i--) {
            for (int j = 0; j <Math.min(k,i); j++) {
                boolean exch=false;
                if(nums[j]>nums[j+1]){
                    exch=true;
                    k=j;
                    int temp=nums[j];
                    nums[j]=nums[j+1];
                    nums[j+1]=temp;
                }
                //这一趟冒泡没有交换元素,说明数组已经有序
                if(!exch)break;
            }
        }
    }

第三种优化思路:鸡尾酒排序

吃完饭在更!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值