歸並排序原理詳解!


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

申請一定量的動態空間,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]。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM