二路歸併排序

2021-07-30 14:47:31 字數 1946 閱讀 8433

將兩個按值有序序列合併成乙個按值有序序列,則稱之為二路歸併排序,下面有自底向上和自頂向下的兩種排序演算法,自頂向下的排序在本文末講述,使用遞迴實現,**較簡潔,經供參考。

1. 歸併子演算法:把位置相鄰的兩個按值有序序列合併成乙個按值有序序列。例如把序列 x[s..u] = 和 序列 x[u+1..v] = 合併成序列

z[s..v] = , 注意合併前的元素都位於同乙個有序序列的相鄰位置,合併後的有序序列的下標與合併前的序列總的起始下標相同。

演算法過程中需要三個整型變數,i 用來遍歷歸併的前乙個有序序列,其初始位置是s;j 用來遍歷歸併的後乙個有序序列,其初始值是u+1;q 用來指出歸併後得到的有序序列的末尾元素的位置,其初始值是s。當遍歷完成其中的乙個有序序列之後,只需把另乙個未結束有序序列的剩餘元素複製到合併後的有序序列的末尾。

看**:

[cpp] view plain copy

print?

//將有序的x[s..u]和x[u+1..v]歸併為有序的z[s..v]

void merge(int x, int z, int s, int u, int v)

while( i <= u ) //將x中剩餘元素x[i..u]複製到z

z[q++] = x[i++];

while( j <= v ) //將x中剩餘元素x[j..v]複製到z

z[q++] = x[j++];

} 2. 一趟歸併掃瞄子演算法:將參加排序的序列分成若干個長度為 t 的,且各自按值有序的子串行,然後多次呼叫歸併子演算法merge將所有兩兩相鄰成對的子串行合併成若干個長度為

2t 的,且各自按值有序的子串行。

若某一趟歸併掃瞄到最後,剩下的元素個數不足兩個子串行的長度時:

若剩下的元素個數大於乙個子串行的長度 t 時,則再呼叫一次歸併子演算法 merge 將剩下的兩個不等長的子串行合併成乙個有序子串行

若剩下的元素個數小於或者等於乙個子串行的長度 t 時,只須將剩下的元素依次複製到前乙個子串行後面。

看**:

[cpp] view plain copy

print?

/* x[0..n-1]表示參加排序的初始序列

* t為某一趟歸併時子串行的長度

* 整型變數i指出當前歸併的兩個子串行中第1個子序列的第1個元素的位置

* y[0..n-1]表示這一趟歸併後的結果

*/void mergepass(int x, int y, int n, int t)

if( n - i > t ) //若最後剩下的元素個數大於乙個子串行的長度t時

merge(x, y, i, i + t - 1, n - 1);

else

//n-i <= t時,相當於只是把x[i..n-1]序列中的資料賦值給y[i..n-1]

for( j = i ; j < n ; ++j )

y[j] = x[j];

} 3. 二路歸併排序演算法:將參加排序的初始序列分成長度為1的子串行使用mergepass函式進行第一趟排序,得到 n / 2 個長度為 2 的各自有序的子串行(若n為奇數,還會存在乙個最後元素的子串行),再一次呼叫mergepass函式進行第二趟排序,得到 n / 4 個長度為 4 的各自有序的子串行, 第 i 趟排序就是兩兩歸併長度為 2^(i-1) 的子串行得到 n / (2^i) 長度為 2^i 的子串行,直到最後只剩乙個長度為n的子串行。由此看出,一共需要 log2n 趟排序,每一趟排序的時間複雜度是 o(n), 由此可知

該演算法的總的時間複雜度是是 o(n log2n),但是該演算法需要 o(n) 的輔助空間,空間複雜度很大,是 o(n).

看**:

[cpp] view plain copy

print?

void mergesort(int x, int n)

free(y);

}

歸併排序(二路歸併)

歸併排序是一種遞迴思想的體現,通過多次合併較小的幾個 二路歸併為兩個 有序陣列形成新的有序表。思路 將陣列分為n nn個一元組,兩兩合併得到二元組,以此類推共合併log 2n log 2n log2 n 次後,陣列變得有序。時間複雜度為o n logn o nlogn o nlog n 編譯環境de...

二路歸併排序

不是困難的演算法,不過也是練習了下遞迴。include include include using namespace std const int maxn 100 5 int a maxn int b maxn void mergesort int a,int b,int begin,int en...

二路歸併排序

二路歸併排序是將兩個有序表合併成乙個有序表的排序方法。其基本思想為 序列中有 n個記錄,可以看作為 n個有序子串行,每個序列長度為 1。首先將每相鄰的兩個記錄合併,得到 n 2 個較大的有序子串行,每個序列長度為 2。再將上述子串行兩兩合併,得到 n 2 2 個有序子串行,直至得到乙個長度為 n的有...