常見排序演算法效能測試

2021-07-26 11:38:30 字數 2904 閱讀 1683

氣泡排序方法是最簡單的排序方法。這種方法的基本思想是,將待排序的元素看作是豎著排列的「氣泡」,較小的元素比較輕,從而要往上浮。在氣泡排序演算法中我們要對這個「氣泡」序列處理若干遍。所謂一遍處理,就是自底向上檢查一遍這個序列,並時刻注意兩個相鄰的元素的順序是否正確。如果發現兩個相鄰元素的順序不對,即「輕」的元素在下面,就交換它們的位置。顯然,處理一遍之後,「最輕」的元素就浮到了最高位置;處理二遍之後,「次輕」的元素就浮到了次高位置。在作第二遍處理時,由於最高位置上的元素已是「最輕」元素,所以不必檢查。一般地,第i遍處理時,不必檢查第i高位置以上的元素,因為經過前面i-1遍的處理,它們已正確地排好序。

對於n位的數列則有比較次數為 (n-1) + (n-2) + … + 1 = n * (n - 1) / 2,這就得到了最大的比較次數

而o(n^2)表示的是複雜度的數量級。舉個例子來說,如果n = 10000,那麼 n(n-1)/2 = (n^2 - n) / 2 = (100000000 - 10000) / 2,相對10^8來說,10000小的可以忽略不計了,所以總計算次數約為0.5 * n^2。用o(n^2)就表示了其數量級(忽略前面係數0.5)。

/**

* 氣泡排序演算法

*/public

static

void

bubble(int arr)}}

}/** * 將兩個變數值調換

*@param a

*@param b

*/private

static

void

change(int a, int b,int arr)

對比陣列中前乙個元素跟後乙個元素的大小,如果後面的元素比前面的元素小則用乙個變數k來記住他的位置,接著第二次比較,前面「後乙個元素」現變成了「前乙個元素」,繼續跟他的「後乙個元素」進行比較如果後面的元素比他要小則用變數k記住它在陣列中的位置(下標),等到迴圈結束的時候,我們應該找到了最小的那個數的下標了,然後進行判斷,如果這個元素的下標不是第乙個元素的下標,就讓第乙個元素跟他交換一下值,這樣就找到整個陣列中最小的數了。然後找到陣列中第二小的數,讓他跟陣列中第二個元素交換一下值,以此類推。

總的比較次數n=(n-1)+(n-2)+…+1=n*(n-1)/2。交換次數o(n),最好情況是,已經有序,交換0次;最壞情況交換n-1次,逆序交換n/2次。交換次數比氣泡排序少多了,由於交換所需cpu時間比比較所需的cpu時間多,n值較小時,選擇排序比氣泡排序快。

/**

* 選擇排序

*/public

static

void

select(int arr)

}

將初始序列中的第乙個元素作為乙個有序序列,然後將剩下的 n-1 個元素按關鍵字大小依次插入該有序序列,每插入乙個元素後依然保持該序列有序,經過 n-1 趟排序後使初始序列有序。

如果目標是把n個元素的序列公升序排列,那麼採用插入排序存在最好情況和最壞情況。最好情況就是,序列已經是公升序排列了,在這種情況下,需要進行的比較操作需(n-1)次即可。最壞情況就是,序列是降序排列,那麼此時需要進行的比較共有n(n-1)/2次。插入排序的賦值操作是比較操作的次數加上 (n-1)次。平均來說插入排序演算法的時間複雜度為o(n^2)。

/**

*插入排序

*/public

static

void

insert(int arr)else

}//迴圈結束後j==-1

if(j==-1)}}

找乙個值作為參考值,比參考值大的就放在右邊,比參考值小的就放在左邊。那麼一趟完成後就將陣列分成了兩部分:參考值左邊的都是小於參考值的數,參考值右邊的都是大於參考值的數,然後分別遞迴求這兩部分,最後得到的就是乙個排好序的陣列了。

快速排序每次將待排序陣列分為兩個部分,在理想狀況下,每一次都將待排序陣列劃分成等長兩個部分,則需要logn次劃分。

而在最壞情況下,即陣列已經有序或大致有序的情況下,每次劃分只能減少乙個元素(中間位置元素),這樣的結果就好比是氣泡排序,所以快速排序時間複雜度下界為o(nlogn),最壞情況為o(n^2)。

- **實現

public

static

void

quicksort(int arr,int low, int high)

while(l//左右兩邊沒有出現交叉,並且左邊沒由找到比關鍵數大的,則索引右移

if(l//將在左側找到的比關鍵數大的值與右邊索引對應的值交換,開始從右側查詢,右側索引值左移

int temp = arr[h];

arr[h] = arr[l];

arr[l] = temp;

h--;

}}//當l==h出現交叉時,跳出迴圈,也就是找到了中間點,接下來從中間點左右分開,再次分別查詢

//此時左邊的數均小於右邊的數

if(l>low)

if(h1,high);}}

在這裡再介紹下隨機化快排:

隨機化快排是建立在基本快排的演算法上做出的改進,利用概率事件降低快排出現的最不利情況的可能性,也就是說:基本的快速排序選取第乙個元素作為關鍵數。這樣在陣列已經有序的情況下,每次劃分將得到最壞的結果。而隨機快排是選取乙個元素作為關鍵數。這種情況下雖然最壞情況仍然是o(n^2),但最壞情況不再依賴於輸入資料,而是由於隨機函式取值不佳。實際上,隨機化快速排序得到理論最壞情況的可能性僅為1/(2^n)。所以隨機化快速排序可以對於絕大多數輸入資料達到o(nlogn)的期望時間複雜度。

這裡使用十萬條資料進行測試,分別用每一種演算法進行(之所以使用十萬條資料而不是百萬條千萬條,是受到個人電腦配置限制,而且快排時使用到遞迴後,資料量過大,造成棧記憶體溢位)

測試選擇排序演算法效能

主函式import helper.sorttesthleper public class selectionsort temp a i a i a minindex a minindex temp public static void main string args import j a.util...

常見的排序演算法效能對比

排序法 平均時間 最差情形 穩定度額外空間 備註冒泡 o n2 o n2 穩定 o 1 n小時較好 交換 o n2 o n2 不穩定o 1 n小時較好 選擇 o n2 o n2 不穩定o 1 n小時較好 插入 o n2 o n2 穩定 o 1 大部分已排序時較好 基數o logrb o logrb ...

效能測試常見指標

1 vuser虛擬使用者 virtual user,模擬真實業務邏輯步驟的虛擬使用者,虛擬使用者模擬的操作步驟都被記錄在虛擬使用者指令碼裡。vuser指令碼用於描述vuser在場景中執行的操作。2 transaction事務 事務用來衡量指令碼中一行 或多行 的執行所耗費的時間。指令碼的虛擬使用者執...