冒泡排序
冒泡排序(Bubble Sort)是一种简单的交换排序算法,通过重复地走访过要排序的元素,依次比较两个相邻的元素,如果顺序错误则进行交换。
原理
- 比较相邻的元素,如果第1个比第2个大,则进行交换。
- 对每一对相邻的元素做同样的工作,从最开始第一对到最后一对,最后的元素将会是最大的值。
- 针对所有的元素重复以上的步骤,除了最后1个(已经是最大的值)。
- 持续每次对越来越少的元素重复上述步骤,直到没有任何一对数字需要比较。
图解分析
假设当前存在数组{67,2,23,12,34},需要对其进行冒泡排序,步骤如下所示:
PS:箭头标记操作是将两个元素进行比较,若第1个元素比第2个元素大,则进行交换。
代码实现
public static void bubbleSort(int[] arr) {
int length = arr.length;
for (int i = 0; i < length - 1; i++) {
for (int j = 0; j < length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = temp;
}
}
System.out.print("\n第" + (i + 1) + "轮排序结果: ");
for (int item : arr) {
System.out.print(item + " ");
}
}
}
public static void main(String[] args) {
int[] arr = new int[]{67, 2, 23, 12, 34};
bubbleSort(arr);
}
/*
结果打印:
第1轮排序结果: 2 23 12 34 67
第2轮排序结果: 2 12 23 34 67
第3轮排序结果: 2 12 23 34 67
第4轮排序结果: 2 12 23 34 67
*/
时间复杂度
最坏情况
逆顺序排列,假设有n个数,等差数列: 1+2+3+4+...+n,此时时间复杂度为:O(n^2)。
最好情况
顺序排列,但对于冒泡排序来说,即使有序仍然会对每个元素进行冒泡,此时时间复杂度仍为:O(n^2)。
算法优化
由上述图解过程,不难看出,在第3轮遍历时,不存在元素交换的情况,此时数组已经是有序的,这种情况就没必要再继续冒泡下去,因此需要对程序进行优化。
优化思路
定义1个交换标识flag,赋值为false,若经历一轮冒泡,有交换元素,则为true;若没有交换元素,则为false;最后通过交换标识的值,判断是否需要进行下一轮冒泡。
代码示例
public static void bubbleSortOptimize(int[] arr) {
int length = arr.length;
boolean flag = false; // 交换标识
for (int i = 0; i < length - 1; i++) {
flag = false; // 重置交换标识
for (int j = 0; j < length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = temp;
flag = true;
}
}
System.out.print("\n第" + (i + 1) + "轮排序结果: ");
for (int item : arr) {
System.out.print(item + " ");
}
if (!flag) break;
}
}
public static void main(String[] args) {
int[] arr = new int[]{67, 2, 23, 12, 34};
bubbleSortOptimize(arr);
}
/*
结果打印:
第1轮排序结果: 2 23 12 34 67
第2轮排序结果: 2 12 23 34 67
第3轮排序结果: 2 12 23 34 67
*/
时间复杂度
最坏情况
最坏情况仍是逆顺序排列,时间复杂度为:O(n^2)。
最好情况
顺序排列,由于在第一轮冒泡过程中,交换标识flag为false,不需要进行后续的冒泡,因此时间复杂度为:O(n)。