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));
}
}
}