首页 > 技术文章 > 排序算法——冒泡排序

niujifei 2019-11-04 21:30 原文

一、基本介绍

  冒泡排序(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     }

 

 

 

 

推荐阅读