- 示例:
int[] array = { 300, 1000, 1, 1200, 2000, 350, 500, 800 };
int temp = 0;
// 比较相邻元素
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length - i - 1; j++) {
if (array[j + 1] < array[j]) {
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
System.out.println("i=" + i + ":" + "j=" + j + ":"
+ "*****************");
// 打印数组
for (int k = 0; k < array.length; k++) {
System.out.println(array[k]);
}
}
}
}
- 每次交换的结果打印(括号标红的是发生交换的两个数,黑体是下一轮参与比较的数):
i=0:j=1:*****************
300;【1;1000】1200;2000;350;500;800
i=0:j=4:*****************
300;1;1000;1200;【350;2000】500;800
i=0:j=5:*****************
300;1;1000;1200;350;【500;2000】800
i=0:j=6:*****************
300;1;1000;1200;350;500;【800;2000】
i=1:j=0:*****************
【1;300】1000;1200;350;500;800;2000
i=1:j=3:*****************
1;300;1000;【350;1200】500;800;2000
i=1:j=4:*****************
1;300;1000;350;【500;1200】800;2000
i=1:j=5:*****************
1;300;1000;350;500;【800;1200】2000
i=2:j=2:*****************
1;300;【350;1000】500;800;1200;2000
i=2:j=3:*****************
1;300;350;【500;1000】800;1200;2000
i=2:j=4:*****************
1;300;350;500;【800;1000】1200;2000
由上总结下冒泡的特点:
- 1、本例是从小到大排序
交换判断是
array[j + 1] < array[j]
就是后面一个数小于前一个数发生交换,让大数后移,因此每次交换都会把小数向前推
- 2、本例是从前向后冒泡的(就是把被比较数后移),一次内循环大数向后移动一次
注意:为什么是从前向后冒泡呢?为什么这里不说让小数前移一次呢?看关键代码:
if (array[j + 1] < array[j]) {
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
……
}
可以看出被比较的数 array[j+1] 比 array[j] 位置靠后,每次发生交换,都是 array[j+1] 向后移动,所以属于向后冒泡
- 3、一次外循环(一趟冒泡)选出当前大数、次大数、次次大数......
观察一下两个循环语句:
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length - i - 1; j++) {
……
}
}
外循环控制比较的个数,内循环负责遍历出本轮最大值
外循环是如何控制个数的呢?通过控制内循环参数的取值范围,每次外循环 i 加一,内循环 j 就会的取值范围就会减一
内循环取值越小,也验证了遍历一轮,大数已经放在本轮最大的位置上了
最终第一趟冒泡会选出最大值,第二趟冒泡选出次大值,以此类推。
第一趟冒泡结果:
i=0:j=6:*****************
300;1;1000;1200;350;500;【800;2000】
第二趟冒泡结果:i=1:j=5:*****************
1;300;1000;350;500;【800;1200】2000
第三趟冒泡结果:
i=2:j=4:*****************
1;300;350;500;【800;1000】1200;2000
这是非常重要的一个细节,有时候看结果都不容易看出来,看代码更容易出错,研究for循环非常有意思