冒泡排序: 双层循环进行比较,外层循环控制比较趟数,内层循环控制比较交换次数,每趟结束后最大值都在末尾。
改进的思路是 减少外层循环次数和内层循环的次数。推荐使用改版二,它2个次数都能修改。
经典版本
缺点是某趟已经有序时,后面的次数还是会继续,外层循环次数总是max,内层循环次数还是 max - i
// 缺点是已经有序时,后面的次数还是会继续,注意内部的上限是 max-i
public static void sort(int[] intArr) {
//max为 数组长度-1
int max = intArr.length - 1;
for (int i = 0; i < max; i++) {
System.out.println("第" + (i + 1) + "趟");
for (int j = 0; j < max - i; j++) {
if (intArr[j] > intArr[j + 1]) {
//2数互换
int temp = intArr[j];
intArr[j] = intArr[j + 1];
intArr[j + 1] = temp;
}
System.out.println("比较次数:" + (j + 1) + ", 结果:" + Arrays.toString(intArr));
}
}
}
改版1: 假设每趟都是有序,如果发生交换则表示无序
缺点是某趟 局部有序时,内层循环次数还是 max - i
public static void sort(int[] intArr) {
//max为 数组长度-1
int max = intArr.length - 1;
for (int i = 0; i < max; i++) {
System.out.println("第" + (i + 1) + "趟");
//假设每一趟开始都是有序
boolean flag = true;
for (int j = 0; j < max - i; j++) {
if (intArr[j] > intArr[j + 1]) {
//2数互换
int temp = intArr[j];
intArr[j] = intArr[j + 1];
intArr[j + 1] = temp;
flag = false;
}
System.out.println("比较次数:" + (j + 1) + ", 结果:" + Arrays.toString(intArr));
}
if (flag) {
break;
}
}
}
改版2(推荐): 假设每趟都是有序,如果发生交换则表示无序,同时记录最后一次发生交换的下标,内层循环最大值就是它
//这个更高效 可以减少局部有序的比较次数
//第一次排序后部分已经有序, 那么开始比较的位置就往前了
public static void sort(int[] intArr) {
//max为 数组长度-1
int max = intArr.length - 1;
//记录上次发生交换位置的index
int secondCount = max;
for (int i = 0; i < max; i++) {
System.out.println("第" + (i + 1) + "趟");
//假设每一趟开始都是有序
boolean flag = true;
int lastChangeIndex = 0;
for (int j = 0; j < secondCount; j++) {
if (intArr[j] > intArr[j + 1]) {
//2数互换
int temp = intArr[j];
intArr[j] = intArr[j + 1];
intArr[j + 1] = temp;
flag = false;
lastChangeIndex = j;
}
System.out.println("比较次数:"+(j+1)+", 结果:"+ Arrays.toString(intArr));
}
if (flag) {
break;
}
//循环完后 得到最后的发生交换时下标
secondCount = lastChangeIndex;
}
}