一、基本介绍
冒泡排序(Bubble Sorting)的基本思想是:
通过对待排序列从前向后(从下标较小的元素开始),依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就像水底的气泡一样逐渐向上冒。
优化:
因为排序的过程中,各元素不断接近自己的位置,如果一趟比较下来没有进行过交换,就说明序列有序。因此要在排序过程中设置一个标志 flag 判断元素是否进行过交换,从而减少不必要的比较。
二、演示冒泡过程的例子(图解)
总结图解过程:
(1)一共进行 数组的大小-1 次 大的循环
(2)每一趟排序的次数在逐渐的减少
(3)如果发现在某趟排序中,没有发生一次交换,可以提前结束冒泡排序,这就是优化。
三、冒泡排序应用实例
将五个无序的数:3,9,-1,10,-2 使用冒泡排序法将其排成一个从小到大的有序数列。
代码实现:
1 import java.text.SimpleDateFormat; 2 import java.util.Arrays; 3 import java.util.Date; 4 5 public class BubbleSort { 6 7 public static void main(String[] args) { 8 int arr[] = { 3, 9, -1, 10, -2 }; 9 10 //测试冒泡排序(无优化) 11 bubbleSort1(arr2); 12 13 // 测试一下冒泡排序的速度O(n^2),给80000个数据,测试 14 // 创建要给 80000 个随机的数组 15 int[] arr2 = new int[80000]; 16 for(int i = 0;i < 80000;i++) { 17 arr2[i] = (int)(Math.random()*80000); 18 } 19 20 Date date1 = new Date(); 21 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 22 String date1String = format.format(date1); 23 System.out.println("排序前的时间是="+date1String); 24 25 //测试冒泡排序 26 bubbleSort2(arr2); 27 28 Date date2 = new Date(); 29 String date2String = format.format(date2); 30 System.out.println("排序后的时间是="+date2String); 31 32 33 } 34 35 // 将前面的冒泡排序算法,封装成一个方法,优化前的方法 36 public static void bubbleSort(int[] arr) { 37 // 冒泡排序的时间复杂度为 O(n^2) 38 int temp = 0; //临时变量 39 for(int i = 0;i < arr.length - 1;i++) { 40 41 for(int j = 0; j< arr.length - 1 - i; j++) { 42 // 如果前面的数比后面的数大,进行交换 43 if (arr[j] > arr[j + 1]) { 44 temp = arr[j]; 45 arr[j] = arr[j + 1]; 46 arr[j + 1] = temp; 47 } 48 } 49 System.out.println("第"+(i+1)+"趟排序后的数组"); 50 System.out.println(Arrays.toString(arr)); 51 } 52 } 53 54 55 56 // 将前面的冒泡排序算法,封装成一个方法,优化后的方法 57 public static void bubbleSort2(int[] arr) { 58 // 冒泡排序的时间复杂度为 O(n^2) 59 int temp = 0; //临时变量 60 boolean flag = false; // 标识变量,标识是否进行过交换 61 for(int i = 0;i < arr.length - 1;i++) { 62 63 for(int j = 0; j< arr.length - 1 - i; j++) { 64 // 如果前面的数比后面的数大,进行交换 65 if (arr[j] > arr[j + 1]) { 66 flag = true; 67 temp = arr[j]; 68 arr[j] = arr[j + 1]; 69 arr[j + 1] = temp; 70 } 71 } 72 73 System.out.println("第"+(i+1)+"趟排序后的数组"); 74 System.out.println(Arrays.toString(arr)); 75 76 if(!flag) { // 在一趟排序中,一次交换都没有发生过 77 break; 78 }else { 79 flag = false; //重置flag,进行下次判断 80 } 81 } 82 } 83 84 } 85