數據結構之各種排序的比較

(一)直接插入排序

算法簡潔,但是隻有當待排元素n比較少的時候效率才高
所需空間:一個當前元素的哨兵array[0]即可
所需時間:主要與所需關鍵字的比較次數及移動的次數有關
最壞的情況——逆序:總的比較次數爲n(n-1)/2,記錄的移動次數也爲n(n-1)/2
最好的情況——正序:比較次數爲n-1,記錄移動次數爲0
由此可以推斷出插入排序算法的平均時間爲O(n^2),最壞的情況爲O(n^2),輔助存儲爲O(1),算法優化:減少比較和移動的次數
穩定性:穩定的,插入排序本就是在一個有序的序列裏插入一個新的元素,當遇到兩個或多個一樣的元素時,自然是一律放到相同元素的最後面,所以這是穩定的
(二)希爾排序
也屬於插入排序類,又稱減小增量排序
基本思想:將序列由某一個變化的增量分爲若干子序列,再對這些子序列進行直接插入排序,等到整個序列基本有序的時候,再對整體進行一次直接插入排序
出發點:直接插入排序在n值較小以及在序列大致有序的時候效率很高
穩定性:我們知道一次插入排序是穩定的,不會改變相同元素的相對順序,但在不同的插入排序過程中,相同的元素可能在各自的插入排序中移動,最後其穩定性就會被打亂,所以shell排序是不穩定的。
希爾排序的時間會比直接插入排序少,但是少多少依賴於增量序列的函數,無法討論
(三)冒泡排序
最壞情況——逆序:需要進行n(n-1)/2次比較,n-1次排序,n(n-1)/2次記錄的移動
最好情況——正序:需要進行n-1次比較,0次排序,0次移動
穩定性:冒泡排序交換的是兩個相鄰元素,如果兩個元素相等,我們是不會交換兩個元素的位置的,所以這個排序是穩定的
(四)快速排序
平均時間:O(nlogn),在平均時間性能上來說屬於最佳的排序算法
最壞情況——逆序:O(n^2)
輔助存儲:O(logn)
快排所需時間爲:一次對整體記錄進行劃分的時間 + 對前k-1個記錄進行快排的時間 + 對後n-k個記錄進行快排的時間,當然,一次對整體進行劃分的時間和n值成正比的
穩定性:快排有兩個指針low、high和一個key,key一般爲第一個元素,也就是樞軸,j往前走,當j的內容小於key的時候,i就往後走,當i的內容大於key的時候,i和j的內容就互換,當i>j的時候,i和key互換內容,這是一趟排序,這時候很容易把穩定性打亂的
(五)堆排序
堆排序適用於n值較大的文件,但對於n值較小的還是選擇希爾排序之類吧
最壞情況和平均時間是一樣的:O(nlogn)
輔助空間:O(1)即:一個記錄大小共交換的空間
性能分析:1、堆排序是基於完全二叉樹的,對於深度爲k的堆,至多2^k-1個記錄,我們從最後一個非終端結點2^(k-1)的記錄開始篩選並建立一個大頂堆,此時與關鍵字的比較次數至多爲2(k-1)次;2、在建立堆的時候,由第i層記錄至多2^(i-1)次,以它們爲根的記錄深度爲h-i-1,那麼調用n/2次篩選算法的時候,與關鍵字比較的次數至多爲4n次;再看,n記錄的完全二叉樹深度爲log2n+1,那麼建立新堆調用n-1次篩選算法,總共的比較次數不超過2n(log2n),也就是O(nlog2n)
穩定性:目前只知道這是不穩定的。。。。。有木有大牛能解釋清楚
(六)歸併排序
性能分析:一次歸併排序會調用n/2h次歸併兩個相鄰有序序列的算法,得到一個長度爲2h的有序序列,整個算法會進行log2n次
時間:O(nlogn),最壞情況亦如此
輔助空間:歸併排序需要的空間的比較多,因爲需要存儲一個經過歸併的序列,它所需要的空間爲O(n)
穩定性:歸併排序把序列分爲若干含有1個或2個元素的序列,1個元素的序列默認爲有序,2個元素的可以直接排序,同樣,我們是不會去交換兩個相等元素的值的,這樣將第一次歸併的序列看爲新的子序列,重複歸併直到有序,這期間都是穩定的
(七)基數排序
基本思想:基數排序與前幾種排序均不同,它是將關鍵字分解成若干個原子關鍵字,通過對原子關鍵字的排序來實現對關鍵字的排序,例如3位數的排序可以分爲個位數的排序、十位數的排序、百位數的排序
(採用鏈式存儲結構來實現吧,需要用到隊列)
性能分析:對n個數進行一次未被排序的最低位數的收集時,先對其進行一次分配,時間複雜度爲O(n),然後對其收集,其時間複雜度爲O(rd)(已知關鍵字所含原子關鍵字的取值範圍爲0~d,rd爲原子關鍵字的取值範圍),即一次分配收集的時間複雜度爲O(d(n+rd)),整個排序的收集分配次數依據數值而定,三位數的就需要3次
輔助空間:O(2rd)即:2rd個隊列
所需時間:平均時間和最壞情況的時間一致:O(d(n+rd)),也爲O(d*n)
穩定性:基數排序從低位開始分配、收集,一直到最高位排序完成,是分配和收集的時候是不可能調整兩個相同元素的位置的,是穩定的
(八)綜合分析
1、就平均時間而言,快排最爲優秀,但在最壞情況下不是最好的
2、在n值較大的時候,使用堆排序和歸併排序較爲有效,這其中以歸併排序時間最少,但是需要更多的空間
3、n值較大且關鍵字較小時,基數排序較適合,空間也只需要多加幾個隊列指針即可;而且基數排序是穩定性最強的,快排、堆排序、希爾排序都不穩定

4、從數據存儲結構來看,若排序中記錄未大量移動,可採用順序存儲結構,若記錄大量移動,則可採用靜態鏈表實現(表插入排序、鏈式基數排序)

(源代碼在代碼分享中。。。)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章