常見排序演算法比較

2021-09-01 01:27:35 字數 4063 閱讀 1111

*

** 常見排序演算法比較

*/#include

#include

#include

#include

#define n 10

#define demo 1

void bubblesort(int arr, int n);

void selectsort(int arr, int n);

void quicksort(int arr, int n);

void printarray(int arr, int n);

void generatearray(int arr, int n);

int main(int argc, char *argv)

// 產生隨機列表

void generatearray(int arr, int n) }

}// 快速排序的遞迴實現

void quicksort(int arr, int n)

// 從前向後搜尋

while(i < j && arr[i]

三, 關於隨機數生成的2個函式 srand()種子發生器函式,還有rand()隨機數生成器函式,自己可以參考相關文件。

四, demo巨集來控制是演示還是比較效能用的。當把n調整的很小,比如10的時候,可以設定demo為1,那樣就能列印陣列了,可以看到比較前後的情況。當把n調整到很大比如10000的時候,就把demo設定為0,那樣就不列印陣列,直接比較效能。

氣泡排序

基本概念

氣泡排序(bubblesort)的基本概念是:依次比較相鄰的兩個數,將小數放在前面,大數放在後面。即在第一趟:首先比較第1個和第2個數,將小數放前,大數放後。然後比較第2個數和第3個數,將小數放前,大數放後,如此繼續,直至比較最後兩個數,將小數放前,大數放後。至此第一趟結束,將最大的數放到了最後。在第二趟:仍從第一對數開始比較(因為可能由於第2個數和第3個數的交換,使得第1個數不再小於第2個數),將小數放前,大數放後,一直比較到倒數第二個數(倒數第一的位置上已經是最大的),第二趟結束,在倒數第二的位置上得到乙個新的最大數(其實在整個數列中是第二大的數)。如此下去,重複以上過程,直至最終完成排序。

由於在排序過程中總是小數往前放,大數往後放,相當於氣泡往上公升,所以稱作氣泡排序。

用二重迴圈實現,外迴圈變數設為i,內迴圈變數設為j。外迴圈重複9次,內迴圈依次重複9,8,...,1次。每次進行比較的兩個元素都是與內迴圈j有關的,它們可以分別用a[j]和a[j+1]標識,i的值依次為1,2,...,9,對於每乙個i, j的值依次為1,2,...10-i。

產生在許多程式設計中,我們需要將乙個數列進行排序,以方便統計,而氣泡排序一直由於其簡潔的思想方法而倍受青睞。

排序過程

設想被排序的陣列r[1..n]垂直豎立,將每個資料元素看作有重量的氣泡,根據輕氣泡不能在重氣泡之下的原則,從下往上掃瞄陣列r,凡掃瞄到違反本原則的輕氣泡,就使其向上"漂浮",如此反覆進行,直至最後任何兩個氣泡都是輕者在上,重者在下為止。

演算法示例

a[0] 、 a[1]、 a[2]、 a[3]、 a[4]、 a[5]、 a[6]:

49 38 65 97 76 13 27

第一趟氣泡排序過程

38 49 65 97 76 13 27

38 49 65 97 76 13 27

38 49 65 97 76 13 27

38 49 65 76 97 13 27

38 49 65 76 13 97 27

38 49 65 76 13 27 97 – 這是第一趟氣泡排序完的結果

第二趟也是重複上面的過程,只不過不需要比較最後那個數97,因為它已經是最大的

38 49 65 13 27 76 97 – 這是結果

第三趟繼續重複,但是不需要比較倒數2個數了

38 49 13 27 65 76 97

…. 選擇排序

基本思想

n個記錄的檔案的直接選擇排序可經過n-1趟直接選擇排序得到有序結果:

①初始狀態:無序區為r[1..n],有序區為空。

②第1趟排序

在無序區r[1..n]中選出關鍵字最小的記錄r[k],將它與無序區的第1個記錄r[1]交換,使r[1..1]和r[2..n]分別變為記錄個數增加1個的新有序區和記錄個數減少1個的新無序區。

…… ③第i趟排序

第i趟排序開始時,當前有序區和無序區分別為r[1..i-1]和r(1≤i≤n-1)。該趟排序從當前無序區中選出關鍵字最小的記錄 r[k],將它與無序區的第1個記錄r交換,使r[1..i]和r分別變為記錄個數增加1個的新有序區和記錄個數減少1個的新無序區。

這樣,n個記錄的檔案的直接選擇排序可經過n-1趟直接選擇排序得到有序結果。

常見的選擇排序細分為簡單選擇排序、樹形選擇排序(錦標賽排序)、堆排序。上述演算法僅是簡單選擇排序的步驟。

排序過程

a[0] 、 a[1]、 a[2]、 a[3]、 a[4]、 a[5]、 a[6]:

49 38 65 97 76 13 27

第一趟排序後 13 [38 65 97 76 49 27]

第二趟排序後 13 27 [65 97 76 49 38]

第三趟排序後 13 27 38 [97 76 49 65]

第四趟排序後 13 27 38 49 [76 97 65]

第五趟排序後 13 27 38 49 65 [97 76]

第六趟排序後 13 27 38 49 65 76 [97]

最後排序結果 13 27 38 49 49 65 76 97

快速排序演算法

演算法過程

設要排序的陣列是a[0]……a[n-1],首先任意選取乙個資料(通常選用第乙個資料)作為關鍵資料,然後將所有比它小的數都放到它前面,所有比它大的數都放到它後面,這個過程稱為一趟快速排序。一趟快速排序的演算法是:

1)設定兩個變數i、j,排序開始的時候:i=0,j=n-1;

2)以第乙個陣列元素作為關鍵資料,賦值給key,即 key=a[0];

3)從j開始向前搜尋,即由後開始向前搜尋(j=j-1),找到第乙個小於key的值a[j],並與a[i]交換;

4)從i開始向後搜尋,即由前開始向後搜尋(i=i+1),找到第乙個大於key的a[i],與a[j]交換;

5)重複第3、4、5步,直到 i=j; (3,4步是在程式中沒找到時候j=j-1,i=i+1,直至找到為止。找到並交換的時候i, j指標位置不變。另外當i=j這過程一定正好是i+或j+完成的最後另迴圈結束)

例如:待排序的陣列a的值分別是:(初始關鍵資料:x=49) 注意關鍵x永遠不變,永遠是和x進行比較,無論在什麼位子,最後的目的就是把x放在中間,小的放前面大的放後面。

a[0] 、 a[1]、 a[2]、 a[3]、 a[4]、 a[5]、 a[6]:

49 38 65 97 76 13 27

進行第一次交換後: 27 38 65 97 76 13 49

( 按照演算法的第三步從後面開始找)

進行第二次交換後: 27 38 49 97 76 13 65

( 按照演算法的第四步從前面開始找》x的值,65>49,兩者交換,此時:i=3 )

進行第三次交換後: 27 38 13 97 76 49 65

( 按照演算法的第五步將又一次執行演算法的第三步從後開始找

進行第四次交換後: 27 38 13 49 76 97 65

( 按照演算法的第四步從前面開始找大於x的值,97>49,兩者交換,此時:i=4,j=6 )

此時再執行第三步的時候就發現i=j,從而結束一趟快速排序,那麼經過一趟快速排序之後的結果是:27 38 13 49 76 97 65,即所以大於49的數全部在49的後面,所以小於49的數全部在49的前面。

快速排序就是遞迴呼叫此過程——在以49為中點分割這個資料序列,分別對前面一部分和後面一部分進行類似的快速排序,從而完成全部資料序列的快速排序,最後把此資料序列變成乙個有序的序列,根據這種思想對於上述陣列a的快速排序的全過程如圖6所示:

初始狀態

進行一次快速排序之後劃分為 49

分別對前後兩部分進行快速排序 經第三步和第四步交換後變成 完成排序。

經第三步和第四步交換後變成 完成排序。

排序演算法比較

本章中已經研究並仔細分析了多個內部排序方法。對於這些內部排序方法之間的比較,主要從以下幾個方面綜合考慮 時間複雜度 空間複雜度 演算法穩定性 演算法簡單性 待排序記錄數 n的大小 記錄本身的資訊量等。選擇n 個整數組成一些隨機排序,各種內部排序方法的實際時間如圖 7 10 所示。從時間複雜度看,所有...

排序演算法比較

排序方法 最好時間 平均時間 最壞時間 輔助儲存 穩定性備註 簡單選擇排序 o n2 o n2 o n2 o 1 不穩定n小時較好 直接插入排序 o n o n2 o n2 o 1 穩定大部分已有序時較好 氣泡排序 o n o n2 o n2 o 1 穩定n小時較好 希爾排序 o n o nlogn...

比較排序演算法

常用的比較排序演算法有 直接插入排序,希爾排序,選擇排序,堆排序,氣泡排序,快速排序,歸併排序等。它們的時間複雜度及空間複雜度為 實現 如下 includeusing namespace std include include 插入排序 void insertsort int a,size t si...