1. 程式人生 > >歸並排序原理詳解!

歸並排序原理詳解!

elf 可能 動態空間 文件合並 you col 相同 治法 lte

無論在空間的利用上還是原理的簡介,使用空間換取時間的代價是必須的!

申請一定量的動態空間,double也是有可能!實際會有許多的問題。

時間復雜度,計算方法如下!因為每次比較都為( k*n/2 )+l*n/4..............如下進行。

一開始的正向分析:考慮如下進行,使用共有log2(n)*(n/k)的比較次數級+同等級數的合並次數。但由於表達的方式不清晰。

T(N) = T(N/2) + O(N);進行時間復雜度的求解。

數學上的遞推表達式可以用來表示------>Dynamic Programming

求解過程如下:

Master thoery(主定理)

推出T(N)=N*T(1)+log(n)*cn

有前後關系的,操作相同的增長序列的拓展規律,

遞歸!遞歸看作一種特殊的動態規劃。

DRY - Don‘t Repeat Yourself 原則

Top-down - 分析方法!復雜問題一種分析方法!自頂向下分解問題

歸並(Merge)排序法是將兩個(或兩個以上)有序表合並成一個新的有序表,即把待排序序列分為若幹個子序列,每個子序列是有序的。然後再把有序子序列合並為整體有序序列。

一次歸並算法

1、基本思路
 設兩個有序的子文件(相當於輸入堆)放在同一向量中相鄰的位置上:R[low..m],R[m+1..high],先將它們合並到一個局部的暫存向量R1(相當於輸出堆)中,待合並完成後將R1復制回R[low..high]中。
 合並過程中,設置i,j和p三個指針,其初值分別指向這三個記錄區的起始位置。合並時依次比較R[i]和R[j]的關鍵字,取關鍵字較小的記錄復制到R1[p]中,然後將被復制記錄的指針i或j加1,以及指向復制位置的指針p加1。
 重復這一過程直至兩個輸入的子文件有一個已全部復制完畢(不妨稱其為空),此時將另一非空的子文件中剩余記錄依次復制到R1中即可。
 實現時,R1是動態申請的,因為申請的空間可能很大,故須加入申請空間是否成功的處理。

Down - top 自底向上的方法

自底向上的基本思想是:第1趟歸並排序時,將待排序的文件R[1..n]看作是n個長度為1的有序子文件,將這些子文件兩兩歸並,若n為偶數,則得到n/2個長度為2的有序子文件;若n為奇數,則最後一個子文件輪空(不參與歸並)。故本趟歸並完成後,前lg n個有序子文件長度為2,但最後一個子文件長度仍為1;第2趟歸並則是將第1趟歸並所得到的lg n個有序的子文件兩兩歸並,如此反復,直到最後得到一個長度為n的有序文件為止。
上述的每次歸並操作,均是將兩個有序的子文件合並成一個有序的子文件,故稱其為"二路歸並排序"。類似地有k(k>2)路歸並排序。
分析:
在某趟歸並中,設各子文件長度為length(最後一個子文件的長度可能小於length),則歸並前R[1..n]中共有個有序的子文件:R
[1..length],R[length+1..2length],…。
調用歸並操作將相鄰的一對子文件進行歸並時,必須對子文件的個數可能是奇數、以及最後一個子文件的長度小於length這兩種特殊情況進行特殊處理:
① 若子文件個數為奇數,則最後一個子文件無須和其它子文件歸並(即本趟輪空);
② 若子文件個數為偶數,則要註意最後一對子文件中後一子文件的區間上界是n。

Top-down 自頂向下的方法


采用分治法進行自頂向下的算法設計,形式更為簡潔。
設歸並排序的當前區間是R[low..high],分治法的三個步驟是:
①分解:將當前區間一分為二,即求分裂點
mid=(low+high)/2

//分裂點的求解過程!無需遵循實際的二分原則,進行就同解
②求解:遞歸地對兩個子區間R[low..mid]和R[mid+1..high]進行歸並排序;
③組合:將已排序的兩個子區間R[low..mid]和R[mid+1..high]歸並為一個有序的區間R[low..high]。

歸並排序原理詳解!