歸併演算法 歸併排序

2022-09-01 11:57:12 字數 1862 閱讀 9512

歸併演算法(歸併排序

這周需要用到歸併演算法, 於是找了找相關的資料, 整理如下:

歸併排序(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是動態申請的,因為申請的空間可能很大,故須加入申請空間是否成功的處理。

、歸併演算法

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

//merge

歸併排序

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

1、 自底向上的方法

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

自底向上的基本思想是:第1趟歸併排序時,將待排序的檔案r[1..n]看作是n個長度為1的有序子檔案,將這些子檔案兩兩歸併,若n為偶數,則得到 個長度為2的有序子檔案;若n為奇數,則最後乙個子檔案輪空(不參與歸併)。故本趟歸併完成後,前 個有序子檔案長度為2,但最後乙個子檔案長度仍為1;第2趟歸併則是將第1趟歸併所得到的 個有序的子檔案兩兩歸併,如此反覆,直到最後得到乙個長度為n的有序檔案為止。

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

(2) 一趟歸併演算法

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

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

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

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

具體演算法如下:

void mergepass(seqlist r,int length)

else

}while (lowptr <= middle)

while (highptr <= upperbound )

//將結果陣列裡的歸併後元素拷回原陣列

for ( int i = 0; i

array [lowerbound+i] = workspace [i];}}

劃分陣列則簡單地用遞迴的方法,下面是排序的方法.

//lowerbound: 待排序陣列的起始索引

//upperbound: 待排序陣列的結束索引

private void sort (int lowerbound, int upperbound)

else

}對於n個元素的陣列來說, 如此劃分需要的層數是以2為底n的對數, 每一層中, 每乙個元素都要複製到結果陣列中, 並複製回來, 所以複製2n次, 那麼對於歸併排序,它的時間複雜度為o(n*logn), 而比較次數會少得多, 最少需要n/2次,最多為n-1次, 所以平均比較次數在兩者之間. 它的主要問題還是在於在記憶體中需要雙倍的空間.

歸併排序演算法

include stdafx.h include include include 合併兩段已經排好序的列表 void merge int list int mergelist int left int mid int right else if i mid else 將列表list按照seglen分...

歸併排序演算法

這個演算法感覺比插入難理解一些,下面說說我的理解 歸併排序的步驟 1.把長度為n的序列分為兩個長度為n 2的子串行 2.對這兩個子串行分別採用歸併排序 3.將兩個子串行合併成乙個最終的排序序列 通過步驟2可看到 在歸併排序中又用了歸併排序,可見這是乙個遞迴的過程。例如乙個陣列 a 8 下面採用遞迴排...

歸併排序演算法

歸併排序 歸併排序演算法是一種o nlogn 的演算法。它的最差,平均,最好時間都是o nlogn 但是它需要額外的儲存空間,這在某些記憶體緊張的機器上會受到限制。include includeusing namespace std int a 10 void merge int fir,int e...