<排序算法三>冒泡排序

一、导入:为什么叫冒泡排序

大家都烧过水吧,是不是每次水快要开的时候烧水容器的底部都会‘咕嘟~’‘咕嘟~’的往上冒泡,先是粘在底部的小泡,在其上升过程中逐渐变大,在达到峰值时啪一下的破裂开来。

冒泡排序的就是这一现象的代码版,算法中的一侧元素会像小气泡一样一点一点的向另一侧移动,当从一侧移动到另一侧时元素小气泡便会都达到峰值,而不一样的是这个峰值可大可小。

比如我们有这样一组数据,整形数组array={1,9,3,8,7,2,6,5,4},我们将数组下标当作从低到高的‘刻度’,而其中的元素当作大小不一的气泡,我们‘底部’开始向上两两比较,让较大的气泡‘超越’较小的气泡,最后在‘顶部’得到一个最大的气泡,如下图:

再重复这个过程,得到次级最大值:

二、冒泡排序算法

冒泡排序(Bublle Sort)是一种基础的交换排序,其思想是把相邻的元素两两比较,当一个元素大(小)于右侧相邻元素时,交换他们的位置;当一个元素小(大)于或等于右侧相邻元素时,位置不变。

以升序排序为例,按照冒泡排序思想从最左侧两两相比至最后一个元素,这一过程是将比过部分最大值不断后移冒泡的过程,不断重复这一过程就会使最右侧有序区间不断扩大(++),最终使数据集整体有序。

当经过n-1轮后所有元素有序,如图:

    public void bubbleSort(int[] array) {
        //共比较n-1轮
        for(int i = 0; i < array.length-1; i++) {
            //有序区间无需排序
            for(int j = 1; j < array.length-i; j++ ) {
                //若右侧元素大于左侧,则交换位置
                if(array[j] < array[j-1]) {
                    //交换
                    swap(array, j-1, j);
                }
            }
        }
    }

三、冒泡排序算法复杂度分析

冒泡排序算法是为数不多的稳定的排序算法,而其算法的比较次数同样稳定,交换次数在最坏情况下,即逆序情况下要使数据集升序排序,那么每次比较都会进行一次交换,共进行(n-1)+(n-2)+...+3+2+1次。

\left ( n-1 \right )+\left ( n-2 \right )+...+3+2+1=\frac{n(n-1)}{2}

因此排序算法的时间复杂度应是O(N^2)

排序过程都在数据集内部操作并不需要额外的空间,因此空间复杂度为O(1)

四、冒牌排序的优化

在最好情况下,即顺序情况下要使数据集升序排序,因为其本身有序,那么每次比较都无需进行交换,这就会造成极大的时间浪费,其实我们只需要判断n-1次确定其是否已经有序即可。

除了本身有序的情况,排序过程中也可能在程序执行过程中就有序了,无需继续判断下去,那么后面这部分时间同样可以省略下来。

优化:每轮排序的同时判断本轮是否进行过交换,若未进行过,则证明已经有序

    public void bubbleSort(int[] array) {
        //共比较n-1轮
        for(int i = 0; i < array.length-1; i++) {
            boolean b = true;
            //有序区间无需排序
            for(int j = 1; j < array.length-i; j++ ) {
                //若右侧元素大于左侧,则交换位置
                if(array[j] < array[j-1]) {
                    //交换
                    swap(array, j-1, j);
                    b = false;
                }
            }
            if(b) {
                break;
            }
        }
    }

博主是Java新人,每位同志的支持都会给博主莫大的动力,如果有任何疑问,或者发现了任何错误,都欢迎大家在评论区交流“ψ(`∇´)ψ

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值