1. 冒泡排序基本介绍
- 冒泡排序(Bubble Sorting)的基本思想是:通过对待排序序列从前向后(从下标较小的元素开始),依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就象水底下的气泡一样逐渐向上冒。
2. 优化
- 因为排序的过程中,各元素不断接近自己的位置,如果一趟比较下来没有进行过交换,就说明序列有序,因此要在排序过程中设置一个标志flag判断元素是否进行过交换。从而减少不必要的比较。(这里说的优化,可以在冒泡排序写好后,在进行)
3. 演示冒泡过程的例子
-
假设原始数组:3, 9, -1, 10, 20
-
如果相邻的元素逆序就交换
-
第一趟排序,经过4次比较,将最大的数排在倒数第一位
(1) 3, 9, -1, 10, 20
(2) 3, -1, 9, 10, 20
(3) 3, -1, 9, 10, 20
(4) 3, -1, 9, 10, 20 -
第二趟排序,经过3次比较,将第二大的数排在倒数第二位
(1) -1, 3, 9, 10, 20
(2) -1, 3, 9, 10, 20
(3) -1, 3, 9, 10, 20 -
第三趟排序,经过2次比较,将第三大的数排在倒数第三位
(1) -1, 3, 9, 10, 20
(2) -1, 3, 9, 10, 20 -
第四趟排序,经过1次比较,将第四大的数排在倒数第四位
(1) -1, 3, 9, 10, 20
4. 小结
- 一共进行数组的大小 -1 次大的循环
- 每一趟排序的次数在逐渐的减少
- 如果我们发现在某趟排序中,没有发生一次交换, 可以提前结束冒泡排序。这个就是优化点,比如上面在第二趟中发生过一次交换(第一步将3,-1变为-1,3),第三趟没有交换,所以第四趟排序可以不执行。
5. 代码实现
import java.util.Arrays;
public class BubbleSort {
public static void main(String[] args) {
int arr[] = {3, 9, -1, 10, 20};
System.out.println("排序前" + Arrays.toString(arr));
analysisProcess(arr);
int arr2[] = {16, 91, 32, 12, 20};
System.out.println("排序前" + Arrays.toString(arr2));
bubbleSort(arr2);
System.out.println("排序后" + Arrays.toString(arr2));
}
/**
* 推导排序过程
* 假设待排序数组是{3, 9, -1, 10, 20},只需进行4轮排序即可
*
* @param arr
*/
public static void analysisProcess(int[] arr) {
// 临时变量
int temp = 0;
// 第一趟排序,将第一大的数排在倒数第一位
for (int i = 0; i < arr.length - 1 - 0; i++) {
// 如果前面的数比后面的大就交换
if (arr[i] > arr[i + 1]) {
// swap(arr[i], arr[i + 1]);
temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
System.out.println("第一趟排序后的数组");
System.out.println(Arrays.toString(arr));
// 第二趟排序,将第2大的数排在倒数第2位
for (int i = 0; i < arr.length - 1 - 1; i++) {
// 如果前面的数比后面的大就交换
if (arr[i] > arr[i + 1]) {
// swap(arr[i], arr[i + 1]);
temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
System.out.println("第二趟排序后的数组");
System.out.println(Arrays.toString(arr));
// 第三趟排序,将第3大的数排在倒数第3位
for (int i = 0; i < arr.length - 1 - 2; i++) {
// 如果前面的数比后面的大就交换
if (arr[i] > arr[i + 1]) {
// swap(arr[i], arr[i + 1]);
temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
System.out.println("第三趟排序后的数组");
System.out.println(Arrays.toString(arr));
// 第四趟排序,将第4大的数排在倒数第4位
for (int i = 0; i < arr.length - 1 - 3; i++) {
// 如果前面的数比后面的大就交换
if (arr[i] > arr[i + 1]) {
// swap(arr[i], arr[i + 1]);
temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
System.out.println("第四趟排序后的数组");
System.out.println(Arrays.toString(arr));
}
/**
* 冒泡排序的时间复杂度 O(n^2)
* 根据上面的分析过程,可以得出下面的规律
*
* @param arr
*/
public static void bubbleSort(int[] arr) {
int temp = 0;
// 标记是否进行过交换
boolean flag = false;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
flag = true;
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
if (!flag) {
// 没有发生交换
break;
}else {
// 本轮排序发生过交换,执行下轮排序前需要重置flag
flag = false;
}
}
}
}
- 结果打印
排序前[3, 9, -1, 10, 20]
第一趟排序后的数组
[3, -1, 9, 10, 20]
第二趟排序后的数组
[-1, 3, 9, 10, 20]
第三趟排序后的数组
[-1, 3, 9, 10, 20]
第四趟排序后的数组
[-1, 3, 9, 10, 20]
排序前[16, 91, 32, 12, 20]
排序后[12, 16, 20, 32, 91]