冒泡排序应用了交换排序的基本思想:两两比较待排序记录,发现两个记录的次序相反则交换,直到没有反序的记录为止。
冒泡排序算法的基本思想:
把每个数据看成一个气泡,按初始顺序自底向上依次对两两气泡进行比较,对上重下轻的气泡交换顺序(这里用气泡轻、重表示数据大、小),保证轻的气泡总能浮在重的气泡上面,直到最轻的气泡浮到最上面;保持最后浮出的气泡不变,对余下气泡循环上述步骤,直到所有气泡从轻到重排列完毕。
因为每一趟排序都使有序区增加了一个气泡,在经过n-1趟排序之后,有序区中就有n-1个气泡,而无序区中气泡的重量总是大于等于有序区中气泡的重量,所以整个冒泡排序过程至多需要进行n-1趟排序。
优化:若在某一趟排序中未发现气泡位置的交换,则说明待排序的无序区中所有气泡均满足轻者在上,重者在下,因此,冒泡排序过程可在此趟排序后终止。在下面给出的实现代码中,引入boolean标记isSwap,在每趟排序开始前,先将其置为false。若排序过程中发生了交换,则将其置为true。各趟排序结束时检查,若未曾发生过交换则终止算法,不再进行下一趟排序。
时间复杂度:冒泡排序是一种用时间换空间的排序方法,最坏情况是把顺序的排列变成逆序,或者把逆序的数列变成顺序。在这种情况下,每一次比较都需要进行交换运算,对于n位的数组则有比较次数为 (n-1) + (n-2) + ... + 1 = n * (n - 1) / 2,这就得到了最大的比较次数,冒泡排序的最坏时间复杂度为O(n2)。若数组的初始状态是已经排好序的,一趟扫描即可完成排序。所需的关键字比较次数为n-1,冒泡排序最好的时间复杂度为O(n)。
1 package com.bingoogol.algorithm.sort; 2 3 /** 4 * 冒泡排序 5 * 6 * @author bingoogol@sina.com 7 */ 8 public class BubbleSort { 9 10 public static void main(String[] args) { 11 int[] arr = new int[] { 2, 6, 30, 25, 9, 18, 13 }; 12 System.out.print("排序前:"); 13 BubbleSort.printArr(arr); 14 BubbleSort.sort(arr); 15 System.out.print("排序后:"); 16 BubbleSort.printArr(arr); 17 } 18 19 public static void sort(int[] arr) { 20 for (int i = 0; i < arr.length - 1; i++) { 21 boolean isSwap = false; 22 // 自下向上扫描 23 for (int j = arr.length - 1; j > i; j--) { 24 if (arr[j] < arr[j - 1]) { 25 isSwap = true; 26 BubbleSort.swap(arr, j, j - 1); 27 } 28 } 29 if (!isSwap) { 30 return; 31 } 32 } 33 } 34 35 public static void swap(int[] data, int i, int j) { 36 int temp = data[i]; 37 data[i] = data[j]; 38 data[j] = temp; 39 } 40 41 public static void printArr(int[] arr) { 42 for (int i = 0; i < arr.length - 1; i++) { 43 System.out.print(arr[i] + ","); 44 } 45 System.out.println(arr[arr.length - 1]); 46 } 47 }