Java冒泡排序优化版

(注:本文是笔者学习完高琪老师关于冒泡排序讲解之后的整理)

1.详解

(1)首先,定义一个待排数组,和用于交换数据的中间变量

(2)然后,先排一次,把最大的数找出来。注意这里的是数组长度-1,因为你用到了values[j+1],不给数组长度-1会越界的!

执行完是酱紫的

可以看到,老大999被排出来了,但是我们发现老二、老三、老爱谁谁 还在人海里漂泊着没归位,所以我们要给剩下的朋友们机会,给他们每人安排一轮排序,帮助他们找到人生的方向

(3)于是我们在这个循环外面加上外层循环

为方便观察,我们加上sout打印一下每次外层循环后的数组信息,截了部分结果图如下:

第1次,同上,把老大哥999找出来了

第2次,把老二22找出来了(老二真的好2啊。。。)

以此类推,到第10次,即数组长度(11) - 1次就完成外层循环了

but!!有没有发现,我们每次外循环都包含11(数组长度)次内循环,特别臃肿有木有,那是因为我们没把之前就排好位子的数据去掉,而是仍然让其参与循环

(4)所以,为了去掉无意义的重复劳动,我们在内层循环中去掉上一次已经排好的那些数。

如当第1次排序完把老大999拎出来了,那第二次排序的时候就不要再管老大的事了,直接在剩下的数中找老二

内循环减个 i 就行,就这么简单~

再看结果(截取部分):

瞬间瘦了有木有!

but!!你有没有发现其实到了第9次外层循环后,数据已经完全排序好了

所以我们就不需要多余的排序了,但是计算机不知道啊,老实的计算机只会执行你的指令,不循环到最后一次决不罢休

(这里的最后一次就是数组长度-1次,如这个数组长度是11,所以循环了10次)

(5)所以,为避免以上尴尬情况,要在每次外循环开始时定义一个标志,意思是说,如果此次外循环所包含的全部内循环都没发生数据交换,就视为已经排序完成,跳出外层循环即可,不再执行多余循环

结果如下

你会说,这不还是10次吗?巧了,这个数组体现不出来,我们稍微改一下,把原数组中的2去掉,即为:

此时数组长度为10,让我们看看需要排序几次吧~要知道没有优化前可是一定会排序9次的啊

只需要6次就完成了

所以有时候优化了一个地方但是体现不明显,可能是测试数据的问题,多试几次就好。

 

 

 

2.代码

/**
 * 冒泡排序(基本 + 优化)
 * 
 * @author Administrator
 *
 */
public class BubbleSort2 {

    public static void main(String[] args) {
        // 待排数组
        int[] values = { 1, 8, 9, 6, 4, 22, 8, 11, 7, 999 };
        // 交换数据的中间变量
        int temp = 0;

        for (int i = 0; i < values.length - 1; i++) {
            //数据是否交换的标志
            boolean flag = true;
            
            System.out.println("第" + (i + 1) + "次外层循环后的结果:");

            for (int j = 0; j < values.length - 1 - i; j++) {
                if (values[j] > values[j + 1]) {
                    temp = values[j];
                    values[j] = values[j + 1];
                    values[j + 1] = temp;
                    
                    //发生数据交换,视为尚未排序完成,改变标志位,不能让外循环结束
                    flag = false;
                }
                System.out.println(Arrays.toString(values));
            }
            
            //如果没有发生数据交换,则视为排序已经完成,就结束外循环
            if(flag) {
                break;
            }
            System.out.println(Arrays.toString(values));
        }
    }
}

  • 17
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值