先从简单的例子开始理解:
一个简单短小的元素从大到小的数组
int [ ]a={4,3,2,1}
将它从小到大排序。
1、先将a[0]=4与a[1]=3进行对比,小的值交换到前面。
前进一格,再将a[1]与a[2]进行对比,小的值交换到前面,并重复当前步骤前进一格,两两对比,直至数组中元素的最大项被“冒泡”到无序数组的最后,则第一轮结束。
第一轮排序结果:经过 3 次两两对比交换,最大值4被排到数组末尾,剩余的无序数组元素剩下{3,2,1}。
2、进行第二轮,以及第三轮,方法同上。
整体过程如下图:
总结规律:
1、一共有a.length个元素,需要经过a.length-1次“冒泡”达到有序(不同的箭头颜色代表不同次冒泡)。每循环一次,都是一次“冒泡过程”。
for(int i=0;i<array.length-1;i++)
2、·每循环一次,都把无序区间中的最大数,冒泡到,无序区间的最后去。
所以:
·数组看作一个整体区间[0,a.length]
·则无序区间是[0,a.length-i]
3、
实现具体的冒泡过程 ,j代表的是蓝色下标。
则
j ~ [0, array.length - i) 无序区间
j + 1 ~ [0, array.length - i) 无序区间 <=> j ~ [-1, array.length - i - 1)
j 需要取交集 [max(0, -1), min(array.length - i, array.length - i - 1))
j ~ [0, array.length - i - 1)
所以:
for (int j = 0; j < array.length - i - 1; j++) {
// j 需要保证 array[j] 和 array[j + 1] 的下标都合法
if (array[j] > array[j + 1]) {
long t = array[j];
array[j] = array[j + 1];
array[j + 1] = t;
}
}
整体冒泡排序:
for(int i=0;i<array.length-1;i++){
for (int j = 0; j < array.length - i - 1; j++) {
// j 需要保证 array[j] 和 array[j + 1] 的下标都合法
if (array[j] > array[j + 1]) {
long t = array[j];
array[j] = array[j + 1];
array[j + 1] = t;
}
}
}