c语言归并排序代码详细注释,C语言实现排序算法之归并排序详解
排序算法中的歸并排序(Merge Sort)是利用"歸并"技術來進行排序。歸并是指將若干個已排序的子文件合并成一個有序的文件。
一、實現原理:
1、算法基本思路
設兩個有序的子文件(相當于輸入堆)放在同一向量中相鄰的位置上:R[low..m],R[m+1..high],先將它們合并到一個局部的暫存向量R1(相當于輸出堆)中,待合并完成后將R1復制回R[low..high]中。
(1)合并過程
合并過程中,設置i,j和p三個指針,其初值分別指向這三個記錄區的起始位置。合并時依次比較R[i]和R[j]的關鍵字,取關鍵字較小的記錄復制到R1[p]中,然后將被復制記錄的指針i或j加1,以及指向復制位置的指針p加1。
重復這一過程直至兩個輸入的子文件有一個已全部復制完畢(不妨稱其為空),此時將另一非空的子文件中剩余記錄依次復制到R1中即可。
最后,將結果賦值的R[]中。
(2)動態申請R1
實現時,R1是動態申請的,因為申請的空間可能很大,故須加入申請空間是否成功的處理。
二、3種方法實現:
算法1:歸并函數都動態分配一個數組,兩個有序數組合并成一個有序數組
算法2:
程序開始處就動態分配一個大數組,避免每次都要創建很多小數組,釋放內存的時候,不會立即釋放。
算法3:
程序開始處分配一個大的數組,只是每次用array[]將數據給tmp[]排好序后,最后再將tmp[]給array[]賦值,這樣就能完成每次調用的時候,入口都一樣。
實現方法二:
歸并排序:將一個無序數組合并成一個有序數組
有兩種實現方法:自底向上和自頂向下
1、 自底向上的方法(自底向上的歸并排序算法雖然效率較高,但可讀性較差。)
(1) 自底向上的基本思想:
自底向上的基本思想是:第1趟歸并排序時,將待排序的文件R[1..n]看作是n個長度為1的有序子文件,將這些子文件兩兩歸并,若n為偶數,則得到n/2個長度為2的有序子文件;若n為奇數,則最后一個子文件輪空(不參與歸并)。故本趟歸并完成后,前logn個有序子文件長度為2,但最后一個子文件長度仍為1;第2趟歸并則是將第1趟歸并所得到的logn個有序的子文件兩兩歸并,如此反復,直到最后得到一個長度為n的有序文件為止。
上述的每次歸并操作,均是將兩個有序的子文件合并成一個有序的子文件,故稱其為"二路歸并排序"。類似地有k(k>2)路歸并排序。
(2) 一趟歸并算法
分析:
在某趟歸并中,設各子文件長度為length(最后一個子文件的長度可能小于length),則歸并前R[1..n]中共有 個有序的子文件:R[1..length],R[length+1..2length],…
注意:
調用歸并操作將相鄰的一對子文件進行歸并時,必須對子文件的個數可能是奇數、以及最后一個子文件的長度小于length這兩種特殊情況進行特殊處理:
① 若子文件個數為奇數,則最后一個子文件無須和其它子文件歸并(即本趟輪空);
② 若子文件個數為偶數,則要注意最后一對子文件中后一子文件的區間上界是n。
具體算法如下:
2、自頂向下的方法
采用分治法進行自頂向下的算法設計,形式更為簡潔。
(1)分治法的三個步驟
設歸并排序的當前區間是R[low..high],分治法的三個步驟是:
①分解:將當前區間一分為二,即求分裂點:mid = (low+high)/2;
②求解:遞歸地對兩個子區間R[low..mid]和R[mid+1..high]進行歸并排序;
③組合:將已排序的兩個子區間R[low..mid]和R[mid+1..high]歸并為一個有序的區間R[low..high]。
遞歸的終結條件:子區間長度為1(一個記錄自然有序)。
具體算法:
三:分析
1、穩定性
歸并排序是一種穩定的排序。
2、存儲結構要求
可用順序存儲結構。也易于在鏈表上實現。
3、時間復雜度
對長度為n的文件,需進行lgn趟二路歸并,每趟歸并的時間為O(n),故其時間復雜度無論是在最好情況下還是在最壞情況下均是O(nlgn)。
4、空間復雜度
需要一個輔助向量來暫存兩有序子文件歸并的結果,故其輔助空間復雜度為O(n),顯然它不是就地排序。
注意:
若用單鏈表做存儲結構,很容易給出就地的歸并排序。
總結
以上是生活随笔為你收集整理的c语言归并排序代码详细注释,C语言实现排序算法之归并排序详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 红帽linux7注册,redhat7.2
- 下一篇: c语言解逻辑问题的一般步骤,C语言面试题