數據結構—排序之冒泡排序
注:此文檔《數據結構與算法之美》的課上學習和自習總結的。屬於原創文章,如發現錯誤,請指出
系列文章
什麼是數據結構?什麼是算法?
數據結構—數組
數據結構—鏈表
數據結構—棧
數據結構—隊列
數據結構—排序
##冒泡排序
-
冒泡排序:冒泡排序只會操作相鄰的兩個數據。每次冒泡操作都會對相鄰的兩個元素進行比較,看是否滿足大小關係要求,如果不滿足就讓他兩個互換,一次至少移動他元素應該在的位置,重複n此,就完成了那個排序工作
-
特點
-
優勢:穩定,空間複雜度O(1),屬於就地(原地)排序算法
-
劣勢:慢,每次只能移動兩個
-
看下圖我們來了解下冒泡排序的過程
-
有序度是一組數據中具有有序元素的個數(比如上面的例子中 5 )
-
滿有序度:一組完全有序的數據(公式:n*(n-1)/2)
-
逆序度是冒泡排序是需要交換元素的次數(等於滿有序度-有序度)
冒泡排序代碼實現1
/**
- 冒泡排序
- 冒泡排序只會操作相鄰的兩個數據。每次冒泡操作都會對相鄰的兩個元素進行比較,看是否滿足大小關係要求。
- 如果不滿足就讓它倆互換。一次冒泡會讓至少一個元素移動到它應該在的位置,重複n 次,
- 就完成了 n 個數據的排序工作。
**/
public class BubbleSort {
public void bubbleSort(Integer[] arr, int n) {
if (n <= 1) return; //如果只有一個元素就不用排序了
for (int i = 0; i < n; ++i) {
// 提前退出冒泡循環的標誌位,即一次比較中沒有交換任何元素,這個數組就已經是有序的了
boolean flag = false;
for (int j = 0; j < n - i - 1; ++j) { //此處你可能會疑問的j<n-i-1,因爲冒泡是把每輪循環中較大的數飄到後面,
// 數組下標又是從0開始的,i下標後面已經排序的個數就得多減1,總結就是i增多少,j的循環位置減多少
if (arr[j] > arr[j + 1]) { //即這兩個相鄰的數是逆序的,交換
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
flag = true;
}
}
if (!flag) break;//沒有數據交換,數組已經有序,退出排序
}
}
public static void main(String[] args) {
Integer arr[] = {2, 4, 7, 6, 8, 5, 9};
SortUtil.show(arr);
BubbleSort bubbleSort = new BubbleSort();
bubbleSort.bubbleSort(arr, arr.length);
SortUtil.show(arr);
}
}
可能大家對上面for (int j = 0; j < n - i - 1; ++j)的這句有點不理解,我幫助大家解釋分析下
- for (int j = 0; j < n - i - 1; ++j) 爲什麼需要 -1。
- 因爲倒數第一個元素如果比倒數倒數第二個元素大,就已經執行了數據交換
- for (int j = 0; j < n - i - 1; ++j) 爲什麼需要 -i,執行下面代碼
public static int[] bubbleSort(int[] a){
if (a.length<=1)return a;
for (int i = 0; i <a.length-1 ; i++) {
if (a[i]>a[i+1]){
int t=a[i];
a[i]=a[i+1];
a[i+1]=t;
}
}
return a;
}
- 大家多次執行上面代碼之後就會發現,每次最大排序後,第一次最大的數在最後面,第二次第二大的數在倒數第二個位置,這次每次循環下來,是不是數據大的是不是默認排序到後面了,所以這裏
-i
冒泡排序代碼實現2
public static int[] bubbleSort2(int[] arr) {
System.out.println(arr.length);
if (arr.length <= 1) return arr;//已經有序
for (int i = 0; i < arr.length; i++) {
for (int j = i + 1; j < arr.length; j++) {
if (arr[i] > arr[j]) {
int a = arr[i];
arr[i] = arr[j];
arr[j] = a;
}
}
}
return arr;
}
上面這個冒泡算法比較簡單,也沒有什麼需要解釋的,大家看下就行。
大家看看下面的這段代碼:
public static int[] bubbleSort(int[] a) {
if (a.length <= 1) return a;
for (int i = 0; i < a.length-1; i++) {
if (a[i] > a[i + 1]) {
int t = a[i];
a[i] = a[i + 1];
a[i + 1] = t;
}
}
return a;
}
假如我們的a數組是這個值: int arr[] = new int[]{1, 25, 2, 35, 14, 58, 10};
我們執行完bubbleSort(arr)後是怎麼樣的結果呢?
這裏我把答案告訴大家:arr={1,2,25,14,35,10,58}
我爲什麼要這麼提示大家注意一下呢?
- 有的人肯定知道了,就是:執行玩一次冒泡操作後,最大和最小值,已經在排序後的兩端了。(我自己終結的,是不是期望大家和我一起多多驗證。)