歸併排序 Merge Sort

2021-06-08 15:10:42 字數 2459 閱讀 4635

歸併排序(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中即可。

(2)動態申請r1

實現時,r1是動態申請的,因為申請的空間可能很大,故須加入申請空間是否成功的處理。

2、歸併演算法

void merge(seqlist r,int low,int m,int high)

//merge 

歸併排序

歸併排序有兩種實現方法:自底向上和自頂向下。

1、 自底向上的方法

(1) 自底向上的基本思想

自底向上的基本思想是:第1趟歸併排序時,將待排序的檔案r[1..n]看作是n個長度為1的有序子檔案,將這些子檔案兩兩歸併,若n為偶數,則得到

參與歸併)。故本趟歸併完成後,前

後乙個子檔案長度仍為1;第2趟歸併則是將第1趟歸併所得到的

序的子檔案兩兩歸併,如此反覆,直到最後得到乙個長度為n的有序檔案為止。

上述的每次歸併操作,均是將兩個有序的子檔案合併成乙個有序的子檔案,故稱其為"二路歸併排序"。類似地有k(k>2)路歸併排序。

(2) 二路歸併排序的全過程

【參見動畫演示

】(3) 一趟歸併演算法

分析:在某趟歸併中,設各子檔案長度為length(最後乙個子檔案的長度可能小於length),則歸併前r[1..n]中共有

[1..length],r[length+1..2length],…,

注意:呼叫歸併操作將相鄰的一對子檔案進行歸併時,必須對子檔案的個數可能是奇數、以及最後乙個子檔案的長度小於length這兩種特殊情況進行特殊處理:

① 若子檔案個數為奇數,則最後乙個子檔案無須和其它子檔案歸併(即本趟輪空);

② 若子檔案個數為偶數,則要注意最後一對子檔案中後一子檔案的區間上界是n。

具體演算法如下:

void mergepass(seqlist r,int length)

{ //對r[1..n]做一趟歸併排序

int i;

for(i=1;i+2*length-1<=n;i=i+2*length)

merge(r,i,i+length-1,i+2*length-1);

//歸併長度為length的兩個相鄰子檔案

if(i+length-1(4)二路歸併排序演算法

void mergesort(seqlist r)

{//採用自底向上的方法,對r[1..n]進行二路歸併排序

int length;

for(1ength=1;length注意:

自底向上的歸併排序演算法雖然效率較高,但可讀性較差。

2、自頂向下的方法

採用分治法進行自頂向下的演算法設計,形式更為簡潔。

(1)分治法的三個步驟

設歸併排序的當前區間是r[low..high],分治法的三個步驟是:

①分解:將當前區間一分為二,即求**點

②求解:遞迴地對兩個子區間r[low..mid]和r[mid+1..high]進行歸併排序;

③組合:將已排序的兩個子區間r[low..mid]和r[mid+1..high]歸併為乙個有序的區間r[low..high]。

遞迴的終結條件:子區間長度為1(乙個記錄自然有序)。

(2)具體演算法

void mergesortdc(seqlist r,int low,int high)

{//用分治法對r[low..high]進行二路歸併排序

int mid;

if(low

二、演算法分析

1、穩定性

歸併排序是一種穩定的排序。

2、儲存結構要求

可用順序儲存結構。也易於在鍊錶上實現。

3、時間複雜度

對長度為n的檔案,需進行

4、空間複雜度

需要乙個輔助向量來暫存兩有序子檔案歸併的結果,故其輔助空間複雜度為o(n),顯然它不是就地排序。

注意:若用單鏈表做儲存結構,很容易給出就地的歸併排序。具體【參見練習】。

歸併排序 Merge sort

merge the a s.m and a m 1.t to r s.t template void two merge typet a,typet r,int s,int m,int t while i m r k a i while j t r k a j merge the a 0.n 1 s...

歸併排序(merge sort)

歸併排序 歸併排序是一種遞迴排序演算法,無論陣列元素的原始順序如何,其效能恆定不變。將陣列一分為二,分別排序兩部分元素,再將有序的兩半陣列歸併為乙個有序陣列。歸併步驟比較陣列前一半的元素與陣列的後一半元素,並將較小元素移到臨時陣列,該過程繼續前進,直到其中一半再沒有元素為止。此後只需將其餘元素移到臨...

歸併排序(MergeSort)

merge是左堆 引入的乙個概念,意思是把兩個堆合併成乙個堆。這裡我們把歸併的思想引入到排序中,通過把兩個已排序的資料表合併來對資料進行排序。堆排序利用了遞迴的思想,它的最壞時間複雜度為o nlogn 如下圖所示,由上圖可知,歸併排序需要3個游標,每個游標指向陣列的起始位置,通過比較a aptr 與...