冒泡排序(经典)

思路分析

冒泡排序的基本思想是:

对待排序的元素依次从前往后遍历,比较相邻元素的值,若相邻元素逆序,则交换位置,最终会使得值较大的元素逐渐从前移动到后面,犹如水中气泡冒上来一样。

优化

因为在排序过程中,每个元素都会不断接近自己应在的位置,如果某一趟中没有进行交换,说明已排序完毕。(可新增flag来作为标志)

图解

image-20241031124546183

每一趟"冒泡",就是将最大的那个元素放到待排序元素的最后,且每过一轮,待排序元素减一。

从上面例子明显可见,可以优化。

小结

  1. 一共进行arr.length()-1次排序
  2. 每一趟排序的次数逐渐减少
  3. 如果发现某一次没有交换,就可以结束排序(优化)
  4. 时间复杂度为$O(n^2)$

代码实现

算法性能测试

测试数据大小 花费时间(单位:毫秒)
10000 43
50000 1845
80000 5250
140000 18690

BubbleSort

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.yukinoshita.algorithm.sort;

import java.util.Arrays;
import java.util.Random;

public class BubbleSort {
public static void main(String args[]) {
int[] arr = {3, 9, -1, 10, -2};

System.out.println("排序前:" + Arrays.toString(arr));
bubbleSort(arr);
System.out.println("排序后:" + Arrays.toString(arr));

// 测试算法性能
testPerformance();
}

public static void bubbleSort(int[] arr) {
boolean flag;
for (int i = 0; i < arr.length - 1; i++) {
flag = true;
for (int j = 0; j < arr.length - i - 1; j++) {
if (arr[j + 1] < arr[j]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
flag = false;
}
}
if (flag) break; // 如果一次排序都没有,说明已经有序
}
}

// 测试算法性能的方法
public static void testPerformance() {
int size = 80000; // 数组大小
int[] arr = new int[size];
Random random = new Random();

// 生成无序数组
for (int i = 0; i < size; i++) {
arr[i] = random.nextInt(100000); // 随机数范围可以根据需要调整
}

long startTime = System.currentTimeMillis(); // 记录开始时间
bubbleSort(arr); // 排序
long endTime = System.currentTimeMillis(); // 记录结束时间

System.out.println("排序大小: " + size);
System.out.println("排序时间: " + (endTime - startTime) + " 毫秒");
}
}