冒泡排序是一种基础的交换排序算法,简单的冒泡排序代码比较简单
public static void sort(int[] arr){
int changeNum = 0; //轮询次数
int compareNum = 0; //比较元素次数
int swapNum = 0; //交换元素次数
for(int i =0; i<arr.length-1; i++){
changeNum++;
for(int j=0; j<arr.length-1-i; j++){
compareNum++;
int tem=0;
if(arr[j]>arr[j+1]){
swapNum++;
tem = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tem;
}
}
}
System.out.println("changeNum:" + changeNum + ", compareNum:" + compareNum+", swapNum:"+swapNum);
}
优化1:原始的算法在数列已经是有序的情况下,仍会执行循环。那么如果能判断数列已经有序,就可以提前结束。
public static void sortOptimize1(int[] arr){
int changeNum = 0; //轮询次数
int compareNum = 0; //比较元素次数
int swapNum = 0; //交换元素次数
for (int i = 0; i < arr.length - 1; i++) {
changeNum++;
boolean isSorted = true; //有序标记
for (int j = 0; j<arr.length-1-i; j++) {
int temp = 0;
compareNum++;
if (arr[j] > arr[j + 1]) {
swapNum ++;
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
isSorted = false;
}
}
if (isSorted) {
break;
}
}
System.out.println("changeNum:" + changeNum + ", compareNum:" + compareNum+", swapNum:"+swapNum);
}
优化2:在排序过程中,右边有序的元素会越来越多,但是每一次轮询排序还是会比较已经有序的区域,因此可以记录右边的有序区域范围,轮询到有序区域时就提前结束本次轮询。
public static void sortOptimize2(int[] arr){
int changeNum = 0; //轮询次数
int compareNum = 0; //比较元素次数
int swapNum = 0; //交换元素次数
int sortBorder = arr.length -1; //无序的边界
for (int i = 0; i < arr.length - 1; i++) {
changeNum++;
boolean isSorted = true; //有序标记
int sortBorderTem = sortBorder;
for (int j = 0; j < sortBorder; j++) {
int temp = 0;
compareNum++;
if (arr[j] > arr[j + 1]) {
swapNum ++;
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
isSorted = false;
sortBorderTem = j;
}
}
//循环结束后,记录无序的边界
sortBorder=sortBorderTem;
if (isSorted) {
break;
}
}
System.out.println("changeNum:" + changeNum + ", compareNum:" + compareNum+", swapNum:"+swapNum);
}