內部排序和外部排序小結
一、內部排序的比較:
1、從時間複雜度來看:
簡單選擇排序、直接插入排序和氣泡排序的平均複雜度都為 O(n2),並且實現過程也較為簡單,但是直接插入排序和氣泡排序在最好的情況下時間複雜度可以達到 O(n),而簡單選擇排序則與序列的初始狀態無關。
希爾排序作為插入排序的擴充套件,對較大規模的排序都可以達到很高的效率,但是目前未得出其精確的漸近時間。
堆排序是利用一種稱為堆的資料結構,可以線上性時間內完成建堆,並且在 O(nlogn)內完成排序過程。
快速排序是基於分治的思想,雖然最壞的情況下快排的時間複雜度會到達 O(n2),但快速排序的平均效能可以達到 O(nlogn),在實際應用中常常優於其他的演算法。
歸併排序同樣是基於分治的思想,但由於其分割子序列與初始序列的排序無關,因此它的最好、最壞和平均時間複雜度均為 O(nlogn)。
2、從空間複雜度來說:
簡單選擇排序、插入排序、氣泡排序和希爾排序、堆排序都僅要藉助常數個輔助空間。
快速排序在空間上只使用一個小的輔助棧,用於實現遞迴,平均情況下大小為 O(logn),當然在最壞的情況下可能會增長到 O(n)。
二路歸併排序在合併操作中需要藉助較多的輔助空間用於元素複製,大小為O(n),雖然有方法可以克服這個缺點,但是其代價是演算法會很複雜而且時間複雜度會增加。
3、從穩定性來看:
直接插入排序、氣泡排序、歸併排序和基數排序都是穩定的排序演算法,而簡單選擇排序、快速排序、希爾排序和堆排序都是不穩定的排序方法。
氣泡排序和堆排序在每次迴圈後都能產生當前的最大值或者最小值,而快速排序依次循壞就確定一個元素的最終位置。
由於希爾排序的時間複雜度依賴於增量函式,所以這裡無法準確的給出時間複雜度
演算法種類 | 時間複雜度 | 空間複雜度 | 是否穩定 | ||
最好情況 | 平均情況 | 最壞情況 | |||
直接插入排序 | O(n) | O(n2) | O(n2) | O(1) | 是 |
氣泡排序 | O(n) | O(n2) | O(n2) | O(1) | 是 |
簡單選擇排序 | O(n2) | O(n2) | O(n2) | O(1) | 否 |
希爾排序 | O(n2) | O(n1.3) | O(1) | 否 | |
快速排序 | O(nlogn) | O(nlogn) | O(n2) | O(nlogn) | 否 |
堆排序 | O(nlogn) | O(nlogn) | O(nlogn) | O(1) | 否 |
2-路歸併排序 | O(nlogn) | O(nlogn) | O(nlogn) | O(n) | 是 |
基數排序 | O(d(n+r)) | O(d(n+r)) | O(d(n+r)) | O(r) | 是 |
排序演算法小結:
1、若n較小(n<=50),則可以採用直接插入排序或者簡單選擇排序。由於直接插入排序所需的記錄移動操作較簡單選擇排序多,因而當記錄本身資訊量較大時,用簡單選擇排序較好。
2、若檔案的初始狀態已按關鍵字基本有序,則選擇直接插入或者氣泡排序為宜。
3、若n較大,則應採用時間複雜度為O(nlogn)的排序方法:快速排序、堆排序或歸併排序。快排被認為目前基於比較的內部排序法中最好的方法,當待排序的關鍵字是隨機分佈時,快速排序的平均時間最短。
堆排序所需的輔助空間少於快排,並且不會出現快排可能出現的最壞情況,這兩種排序都是不穩定的。若要求排序穩定且時間複雜度為O(nlogn),則可以選擇歸排序。
4、若n很大,記錄的關鍵字位數較少且可以分解時,採用基數排序較好。
5、當記錄本身資訊量較大時,為避免耗費大量的時間移動記錄。可用連結串列作為儲存結構。
二、外部排序
在記憶體中進行的排序稱為內部排序,而在許多實際應用中,經常需要對大檔案進行排序,因為檔案中的記錄很多,資訊量龐大,無法將整個檔案拷貝進記憶體進行排序。因此,需要將帶排序的記錄儲存在外存上,排序時再把資料一部分一部分的調入記憶體進行排序,在排序中需要多次進行內外存的互動,對外存檔案中的記錄進行排序後的結果仍然被放到原有檔案中。這種排序方法就稱外部排序。
由於外存裝置的不同,外部排序通常分為磁碟檔案排序和磁帶檔案排序。磁碟是直接存取裝置,磁帶是順序存取裝置。
檔案通常是按塊儲存在磁碟上,作業系統也是按塊對磁碟上的資訊進行讀寫的。因為磁碟讀寫的機械運動所需的時間遠遠超過記憶體計算的時間。因此,在外部排序過程中的時間代價主要考慮訪問磁碟的次數,即i/o次數。
外部排序通常採用歸併排序:它包括兩個相對獨立的階段:首先,根據記憶體快取區的大小,將外存上含有n個記錄的檔案分割成若干長度為 h 的子檔案,依次的讀入記憶體並利用有效的內部排序方法對他們進行排序,並將排序後得到的有序子檔案重新寫回外存,通常稱這些有序子檔案為歸併段或者順串。
然後,對這些歸併段進行逐趟歸併,使得歸併段(有序的子檔案)逐漸由小到大,直至得到整個有序檔案為止。
之後還可以採用多路平衡歸併和敗者樹,置換-選擇排序,最佳歸併樹進行處理,這裡就不一一展開了。