1、冒泡排序法概述算法
冒泡排序法的基本思想是:對待排序記錄關鍵字從後往前(逆序)進行多遍掃描,當發現相鄰兩個關鍵字的次序與排序要求的規則不符時,就將這兩個記錄進行交換。這樣,關鍵字較小的記錄將逐漸從後面向前面移動,就像氣泡在水中向上浮同樣,因此該算法也稱爲氣泡排序法。(提示:冒泡排序法也可以使較大的記錄排在前面)
假設須要排序的記錄有n個,其關鍵字保存在數組a中,使用冒泡排序法,需對數組a進行n-1次掃描,完成排序操做,具體過程以下:
(1)將A[n]與A[n-1]進行比較,若A[n]<A[n-1],則交換兩元素的位置。
(2)修改數組下標,使須要比較的兩個元素爲A[n-1]和A[n-2],重複步驟1,對這兩個元素進行比較。重複這個過程,直到對A[2]和A[1]進行比較完爲止。完成第1遍掃描,以下圖所示。編程
3)通過第1遍掃描後,最小的元素已經像氣泡同樣「浮」到最上面,即位於元素A[1]中了。接下來重複前面的步驟,進行第2遍掃描,只是掃描到A[3]與A[2]進行比較完爲止(由於A[1]中已是最小的數據,不用再進行比較)。
(4)經過n-1遍掃描,前n-1個數都已經排序完成,最後一個元素A[n]確定就是最大的數了。至此,完成排序操做。(提示:在以上描述中,爲了讓讀者容易理解,假設數組元素是保存在A[1]~A[n]中的,因爲C語言的數組元素下標是從0開始的,所以,須要修改數組的下標)數組
下面以一組待排序的數據演示冒泡排序的過程,假設有6個須要排序的數據序列以下:
69,65,90,37,92,6
經過冒泡排序法對這6個數據進行排序,其排序過程以下圖所示。函數
第1遍從下向上掃描,首先對最後兩個元素A[5]和A[4]進行比較,因92>6,將6上浮到A[4],92下沉到A[5]。接着將A[4]中的6和A[3]比較,6仍然較小,繼續上浮至A[3]……這樣通過n-1次比較,6上浮到A[0],完成第1遍掃描。此時A[0]中保存着當前數列中的最小數。完成最小數的冒泡過程。測試
第2遍掃描仍然從A[5]開始,至A[1]時結束,將37上浮到A[1]。
相似的方法,在第3遍掃描時,65上浮到A[2]中,至此,全部數都已按從小到大的順序排列,但程序還須要進行第4遍和第5遍的掃描,由於程序並不知道後面的數據是否爲有序的。code
2、冒泡排序法實現排序
(1)冒泡排序法內存
void BubbleSort(int a[], int n) { int i, j, t; for (i=0; i<n; i++) { for (j=n-1; j>i; j--) { if (a[j-1] > a[j]) { t = a[j-1]; a[j-1] = a[j]; a[j] = t; } } printf("第%d遍:", i+1); for (j=0; j<n; j++) printf("%d ", a[j]); printf("\n"); } }
(2)數組顯示io
void ShowData(int arr[], int n) { int i; for (i=0; i<n; i++) printf("%d ", arr[i]); printf("\n"); return; }
(3)冒泡排序法測試class
#include <stdio.h> #define ARRAYLEN 6 int main(int argc, char *argv[]) { int i; int a[ARRAYLEN] = {69, 65, 90, 37, 92, 6}; printf("原數據:"); ShowData(a, ARRAYLEN); BubbleSort(a, ARRAYLEN); printf("排序後:"); ShowData(a, ARRAYLEN); return 0; }
(4)運行結果
3、冒泡排序法改進
從上面的BubbleSort函數的過程能夠看出,使用冒泡排序法對n個數據進行排序,一共須要進行n-1次的比較。若是原本就是有順序的數據,也須要進行n-1次比較。這就形成了冒泡排序法的算法雖然簡單,但效率較差。
爲了提高冒泡排序法的效率,可對BubbleSort函數進行改進,當在某一遍掃描時,發現數據都已經按順序排列了,就再也不進行後面的掃描,而結束排序過程。
如何知道數據已經按順序排好了呢?從上圖能夠看出,當第3遍掃描後,數據已經按順序排列好了,第4遍掃描時將沒有數據進行交換。所以,能夠設置一個標誌變量flag,在每一遍掃描以前將其值設置爲0,在掃描數據過程當中,如有數據交換,則設置其值爲1。在一遍掃描完成以後,判斷flag的值,若其值爲0,表示在這一遍掃描中已經沒有數據進行交換,數據已經按順序排列,就不須要再進行後續的掃描了。
編程經驗:爲了提升排序效率,引進了一個標誌變量。即經過內存空間使用上的增多來使程序執行效率獲得提高,這稱爲「以空間換時間」。
(1)改進冒泡排序法的實現
void BubbleSortNew(int a[], int n) { int i, j, t, flag=0; for (i=0; i<n; i++) { for (j=n-1; j>i; j--) { if (a[j-1] > a[j]) { t = a[j-1]; a[j-1] = a[j]; a[j] = t; flag = 1; } } printf("第%d遍:", i+1); for (j=0; j<n; j++) printf("%d ", a[j]); printf("\n"); if (flag == 0) break; else flag = 0; } }
(2)改進冒泡排序法測試
#include <stdio.h> #define ARRAYLEN 6 int main(int argc, char *argv[]) { int i; int a[ARRAYLEN] = {69, 65, 90, 37, 92, 6}; printf("原數據:"); ShowData(a, ARRAYLEN); BubbleSortNew(a, ARRAYLEN); printf("排序後:"); ShowData(a, ARRAYLEN); return 0; }
(3)運行結果
能夠看出來,當第3遍掃描後,數據已經按順序排列好了,第4遍掃描時將沒有數據進行交換,就再也不進行後面的掃描,而結束排序過程。