什么是冒泡排序(Bubble Sorting)?
通过对待排序序列从前向后(从下标较小的元素开始) ,
依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就象水底下的气泡一样逐渐向上冒。
下面我们来看一个例子:[20,8,-10,9,2]
- ①第一趟排序:
[8,20,-10,9,2];
[8,-10,20,9,2];
[8,-10,9,20,2];
[8,-10,9,2,20]; - ②第二趟排序:
[-10,8,9,2,20];
[-10,8,9,2,20];
[-10,8,2,9,20]; - ③第三趟排序:
[-10,8,2,9,20];
[-10,2,8,9,20]; - ④第四趟排序:
[2,-10,8,9,20];
由以上例子我们可以得出:
- 一共进行数组的大小 -1次大的循环;
- 每一趟排序的次数在逐渐的减少 ;
- 如果我们发现在某趟排序中,没有发生一次交换,可以提前结束冒泡排序。
我们可以写出代码:
import java.util.Arrays;
public class BubbleSort {
public static void main(String[] args) {
//int[] arr = {20,8,-10,9,2};
int[] arr = {1,2,3,4,5};
boolean flag = false;//标识变量,表示是否已经进行过交换
for(int i = 0 ; i< arr.length-1; i++){ //一共要进行 arr.length-1 趟排序
for (int j = 0; j <arr.length-1-i ; j++) {
//每一趟排序: 将最大的数排到最后(5个数:第一趟排序4次;第二趟排序3次...以此类推 所以是arr.length-1-i
//如果前面的数比后面的数大就交换
if(arr[j] > arr[j+1]){
flag = true;//表示已经交换过
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
System.out.println("第"+(i+1)+"趟排序后的数组:");
System.out.println(Arrays.toString(arr));
}
}
}
运行结果如图所示:
但是代码不是最优的,因为当一个数组本来就是有序数组,例如[1,2,3,4,5,6],那么像以上代码运行的话,会重复很多次,这样没有意义。所以我们可以设置一个标志位,来判断是否已经交换过,从而可以提前结束冒泡排序。优化后的代码如下:
import java.util.Arrays;
public class BubbleSort {
public static void main(String[] args) {
int[] arr = {20,8,-10,9,2};
System.out.println("排序前");
System.out.println(Arrays.toString(arr));
bubbleSort(arr);
System.out.println("排序后");
System.out.println(Arrays.toString(arr));
}
public static void bubbleSort(int[] arr){
int temp = 0;//临时变量
boolean flag = false;//标识变量,表示是否已经进行过交换
for(int i = 0 ; i< arr.length-1; i++){ //一共要进行 arr.length-1 趟排序
for (int j = 0; j <arr.length-1-i ; j++) {
//每一趟排序: 将最大的数排到最后(5个数:第一趟排序4次;第二趟排序3次...以此类推 所以是arr.length-1-i
//如果前面的数比后面的数大就交换
if (arr[j] > arr[j + 1]) {
flag = true;//表示已经交换过
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
if(flag == false){ //在一趟排序中,一次都没有交换过
break;
}else{
flag = true;
}
}
}
}
运行结果如图所示: