循环的具体步骤如下所示,自己循环一遍恍然大悟,因为数组是动态改变的,外层循环一次,内层循环都要从头开始,从数组[0]开始比较,这就导致了,如果是正序排序,后面大的结果会和前面小的结果进行比较,交换位置,这便是造成和自己排序想法相违背的原因。
序号 | 0 | 1 | 2 | 3 | 4 | 5 | 设想是正序排序 | ||
小的在坐,大的在右 | |||||||||
3 | 1 | 5 | 0 | 2 | 4 | 如果i大于j则交换位置 | |||
第一次 | 1 | 3 | 5 | 0 | 2 | 4 | 外层i递增一次 | ||
0 | 3 | 5 | 1 | 2 | ? ? ? ?4 | 内层j循环一遍 | |||
序号 | 0 | 1 | 2 | 3 | 4 | 5 | 黄标是i的值 | ||
j的值每次循环从0开始递增 | |||||||||
0 | 3 | 5 | 1 | 2 | 4 | ||||
第二次 | 3 | 0 | 5 | 1 | 2 | 4 | |||
序号 | 0 | 1 | 2 | 3 | 4 | 5 | |||
3 | 0 | 5 | 1 | 2 | 4 | ||||
第三次 | 5 | 0 | 3 | 1 | 2 | 4 | |||
5 | 3 | 0 | 1 | 2 | 4 | ||||
序号 | 0 | 1 | 2 | 3 | 4 | 5 | |||
5 | 3 | 0 | 1 | 2 | 4 | ||||
第四次 | 5 | 3 | 1 | 0 | 2 | 4 | |||
序号 | 0 | 1 | 2 | 3 | 4 | 5 | |||
5 | 3 | 1 | 0 | 2 | 4 | ||||
第五次 | 5 | 3 | 2 | 0 | 1 | 4 | |||
5 | 3 | 2 | 1 | 0 | 4 | ||||
序号 | 0 | 1 | 2 | 3 | 4 | 5 | |||
5 | 3 | 2 | 1 | 0 | 4 | ||||
第五次 | 5 | 4 | 2 | 1 | 0 | 3 | |||
5 | 4 | 3 | 1 | 0 | 2 | ||||
5 | 4 | 3 | 2 | 0 | 1 | ||||
5 | 4 | 3 | 2 | 1 | 0 | ||||
????? 五次循环结束时排序完成,但是排序结果和初衷相违背,是倒序排序。 |
?
主要循环代码如下:
for (int i = 0; i < arrNum.length; i++) {
for (int j = 0; j < arrNum.length; j++) {
if (arrNum[i] > arrNum[j]) {//若arrNum[0]为最大值
int temp = arrNum[i];//临时变量储存一个值
arrNum[i] = arrNum[j];
arrNum[j] = temp;
}
}
}
?
当然若是不想使用冒泡排序,也可以使用这个方法,不过需要进行改进,
以升序排序为例,设想的是小的在左边,大的在右边,
通过上面的第一次排序过程可以发现,第一次排序结果是将最小的值放在了左边,
通过这个结果我们可以知道,这个方法的思路是没问题的,
需要注意的是,要把左边排序好的结果进行固定,防止和后面的值进行交换,
有了这个思路就好办了,只要在下一遍循环的时候,不与排序好的进行比较就行了,代码如下:
for (int i = 0; i < arr.length; i++) {
for (int j = i; j < arr.length - 1; j++) {
if (arr[i] > arr[j + 1]) {
int temp = arr[i];
arr[i] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
这里将 i?的值赋给 i 让每次开始时从排序好的下一位开始比较与i同步,这里的?arr[i] > arr[j + 1]?是让arr[i] 跳过与自己比较,减少代码的循环次数,更加高效,要注意 内层循环条件,要改成 j<arr.length-1? 不然会报错,数组下标溢出数组长度。