package class01;
/**
* 冒泡排序
*
* 另:冒泡排序和选择排序,乍一看很像,只是方向相反。
* 其实不一样,选择排序是,在一次循环中,找到最小值的位置,直接让本次循环的第一个数和最小值交换。之间可能隔着很多数,只是比较了一下,并没有把每组相邻的两个数,一一交换。
* 而冒泡排序是:每次循环都是两两交换,不管本次循环的第一个数和本次循环的最大值,隔着多远。都是让本次循环的最大值,来到本次循环的最后一个位置。
*/
public class Code03_BubbleSort {
public static void main(String[] args) {
int[] arr = {5, 4, 6, 8, 7, 9, 7, 2, 1, 3};
printArr(arr);
bubbleSort(arr);
printArr(arr);
}
public static void bubbleSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
//0~n-1 上,干一堆事
//0~n-2 上,干一堆事
//0~n-3 上,干一堆事
//...
//0~1 上,干一堆事
//0~end (end是变化的,end就代表了n-1,下一次end就是n-2,再下一次end就是n-3)
int N = arr.length;
for (int end = N - 1; end >= 0; end--) {//第一层循环,来控制边界:0~n-1,0~n-2...0~1
//0~end 上干一堆事
//0 1, 1 2, 2 3, 3 4, ... ,end-1 end.
//就是比较索引 0和1的值,谁大。再比较 1和2,2和3,3和4,... 最后是 end-1和end。
//那么就定义一个变量second,作为两两一组中的第二个索引。并锁定边界,second最大会到end,则second <= end。(end就是最后一个)
//或者定义一个变量first,那么:(end-1是最后一个)
//for(int first = 0, first <= end -1; first++){
//}
for (int second = 1; second <= end; second++) {
if (arr[second - 1] > arr[second]) {
swap(arr, second - 1, second);
}
}
}
}
public static void swap(int[] arr, int i, int j) {
int t = arr[j];
arr[j] = arr[i];
arr[i] = t;
}
public static void printArr(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
//博客中看到的优化解法
//1.如果没有元素交换,说明数列已然有序,直接跳出大循环(外层循环),结束。
//2.如果在每一趟的循环中,当指针走到某个位置,发现该位置右侧已经有序,则直接跳出小循环,继续下一趟循环。
public static int[] bubbleSort2(int[] arr) {
if (arr == null || arr.length < 2) {
return arr;
}
//记录最后一次交换的位置
int lastExchangeIndex = 0;
//无序数列的边界,每次比较只需要比到这里为止
int sortBorder = arr.length - 1;
for (int i = 0; i < arr.length - 1; i++) {
boolean isSorted = true;//有序标记,每一轮的初始是true
for (int j = 0; j < sortBorder; j++) {
if (arr[j + 1] < arr[j]) {
isSorted = false;//有元素交换,所以不是有序,标记变为false
int t = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = t;
lastExchangeIndex = j;
}
}
sortBorder = lastExchangeIndex;
//一趟下来是否发生位置交换,如果没有交换直接跳出大循环
if (isSorted) {
break;
}
}
return arr;
}
public static void bubbleSort3(int[] arr) {
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length - i - 1; j++) {
if (arr[j + 1] < arr[j]) {
swap(arr, j + 1, j);
}
}
}
}
}