算法描述
- 依次比较数组中相邻两个元素大小,若 a[j] > a[j+1],则交换两个元素,两两都比较一遍称为一轮冒泡,结果是让最大的元素排至最后
- 重复以上步骤,直到整个数组有序
优化方式:
- 优化点1:每经过一轮冒泡,内层循环就可以减少一次
- 优化点2:如果某一轮冒泡没有发生交换,则表示所有数据有序,可以结束外层循环
- 每轮冒泡时,最后一次交换索引可以作为下一轮冒泡的比较次数,如果这个值为零,表示整个数组有序,直接退出外层循环即可
public class BubbleSort {
public static void main(String[] args) {
int[] arr = {5,9,7,4,1,3,2,8};//冒泡排序数组
bubble_2(arr);
}
/**
* 冒泡排序
* 优化:
* ① 每次排序后已经排序好的就不需要在继续排序了,所以内层循环的值为arr.length-i-1
* ② 若没有进行交换,那么表示数组已经有序了,就不需要再进行循环了,直接退出循环
* @param arr
*/
private static void bubble(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {//比较的次数是数组的长度-1
boolean swapped = false;//判断是否进行交换
//每一次是数组中相邻的两个数进行比较
// for (int j = 0; j < arr.length -1; j++) {//一轮冒泡需要进行多少次比较
for (int j = 0; j < arr.length-i-1; j++) {//每次排序后已经排序好的就不需要在继续排序了
System.out.println("比较次数:"+j);
if(arr[j]>arr[j+1]){
swap(arr,j,j+1);
swapped =true;
}
}
System.out.println("第"+i+"轮冒泡"+arr[i]+"和"+arr[i+1]+"进行交换");
System.out.println("交换结果为:"+Arrays.toString(arr));
//判断是否进行交换,来确定是否已经排好序。
if (!swapped){//若没有进行交换,那么表示数组已经有序了,就不需要再进行循环了。
break;
}
}
System.out.println(Arrays.toString(arr));
}
/**
* 冒泡排序——优化版
* 记录每一轮排序最后一次交换的索引,表示索引之后的数全部已经排好序了,只需要对索引之前的进行排序
* @param arr
*/
private static void bubble_2(int[] arr) {
int n = arr.length-1;//内层循环次数
while (true){
int last = 0; //最后一次交换的索引位置
for (int j = 0; j < n; j++) {
System.out.println("比较次数:"+j);
if (arr[j]>arr[j+1]){
swap(arr,j,j+1);
last = j;
}
}
System.out.println("冒泡+1");
System.out.println("交换结果为:"+Arrays.toString(arr));
n=last;
if (n==0){//
break;
}
}
}
//交换数组中的两个元素位置
public static void swap(int[] arr,int i,int j){
int t = arr[i];
arr[i] = arr[j];
arr[j] =t;
}
}