一、基本介绍
冒泡排序(Bubble Sorting)的基本思想是:
通过对待排序列从前向后(从下标较小的元素开始),依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就像水底的气泡一样逐渐向上冒。
二、演示冒泡过程的例子(图解)
总结图解过程:
(1)一共进行 数组的大小-1 次 大的循环
(2)每一趟排序的次数在逐渐的减少
(3)如果发现在某趟排序中,没有发生一次交换,可以提前结束冒泡排序,这就是优化。
三、冒泡排序实现
将五个无序的数:3,9,-1,10,-2 使用冒泡排序法将其排成一个从小到大的有序数列。
演变过程:
1 int[] arr = {3, 9, -1, 10, -2};
2 int temp = 0; //临时变量,用于交换数据
3
4 //第一趟排序,就是将最大的数排在最后
5 for (int j = 0; j < arr.length - 1 - 0; j++) {
6 // 如果前面的数比后面的数大,进行交换
7 if (arr[j] > arr[j+1]) {
8 temp = arr[j];
9 arr[j] = arr[j+1];
10 arr[j+1] = temp;
11 }
12 }
13 System.out.println("第一趟排序结果:" + Arrays.toString(arr));
14
15
16 //第二趟排序,就是把第二大的数排在倒数第二位
17 for (int j = 0; j < arr.length - 1 - 1; j++) {
18 if (arr[j] > arr[j+1]) {
19 temp = arr[j];
20 arr[j] = arr[j+1];
21 arr[j+1] = temp;
22 }
23 }
24 System.out.println("第二趟排序结果:" + Arrays.toString(arr));
25
26 //第三趟排序,就是把第三大的数排在倒数第三位
27 for (int j = 0; j < arr.length - 1 - 2; j++) {
28 if (arr[j] > arr[j+1]) {
29 temp = arr[j];
30 arr[j] = arr[j+1];
31 arr[j+1] = temp;
32 }
33 }
34 System.out.println("第三趟排序结果:" + Arrays.toString(arr));
35
36 //第四趟排序,就是把第四大的数排在倒数第四位
37 for (int j = 0; j < arr.length - 1 - 1; j++) {
38 if (arr[j] > arr[j+1]) {
39 temp = arr[j];
40 arr[j] = arr[j+1];
41 arr[j+1] = temp;
42 }
43 }
44 System.out.println("第四趟排序结果:" + Arrays.toString(arr));
封装成一个方法:
1 // 将前面的冒泡排序算法,封装成一个方法
2 // 冒泡排序的时间复杂度为 O(n^2)
3 public static void bubbleSort(int[] arr) {
4 int temp = 0; //临时变量
5 for (int i = 0; i < arr.length - 1; i++) {
6 for (int j = 0; j < arr.length - 1 - i; j++) {
7 // 如果前面的数比后面的数大,进行交换
8 if (arr[j] > arr[j+1]) {
9 temp = arr[j];
10 arr[j] = arr[j+1];
11 arr[j+1] = temp;
12 }
13 }
14
15 System.out.println("第"+(i+1)+"趟排序结果:" + Arrays.toString(arr));
16 }
17 }
测试:
1 public class BubbleSort {
2
3 public static void main(String[] args) {
4 int[] arr = {3, 9, -1, 10, -2};
5
6 // 测试一下冒泡排序的速度O(n^2),给80000个数据,测试
7 // 创建要给 80000 个随机的数组
8 int[] arr2 = new int[80000];
9 for(int i = 0;i < 80000;i++) {
10 arr2[i] = (int)(Math.random()*80000);
11 }
12
13 Date date1 = new Date();
14 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
15 String date1String = format.format(date1);
16 System.out.println("排序前的时间是="+date1String);
17
18 //测试冒泡排序
19 bubbleSort(arr2);
20
21
22 Date date2 = new Date();
23 String date2String = format.format(date2);
24 System.out.println("排序后的时间是="+date2String);
25 }
可以看出冒泡排序对80000个数据进行排序,大概需要20秒左右的时间。
四、优化
优化:
因为排序的过程中,各元素不断接近自己的位置,如果一趟比较下来没有进行过交换,就说明序列有序。因此要在排序过程中设置一个标志 flag 判断元素是否进行过交换,从而减少不必要的比较。
对于上面的排序可以发现,在第三趟排序的时候就已经是有序的,这时就可以跳出循环。所以可以标识一个变量,当某一趟排序时不再交换,这时就排序完成了。
优化后的代码:
1 //优化
2 public static void bubbleSort2(int[] arr) {
3 int temp = 0; //临时变量
4 boolean flag = false; //定义一个标识变量,标识是否进行过交换
5 for (int i = 0; i < arr.length - 1; i++) {
6 for (int j = 0; j < arr.length - 1 - i; j++) {
7 // 如果前面的数比后面的数大,进行交换
8 if (arr[j] > arr[j+1]) {
9 flag = true;
10 temp = arr[j];
11 arr[j] = arr[j+1];
12 arr[j+1] = temp;
13 }
14 }
15
16 if (!flag) {
17 break;
18 } else {
19 flag = false;
20 }
21
22 System.out.println("第"+(i+1)+"趟排序结果:" + Arrays.toString(arr));
23 }
24 }