排序演算法 歸併排序

2022-07-14 22:48:23 字數 1996 閱讀 1204

歸併排序完全遵循分治模式,主要操作分為三步:

1.分解:分解待排序的n個元素序列為2個n/2個元素的子串行。

2.解決:使用歸併排序遞迴的排序兩個子串行。

3.合併:合併兩個已排序的子串行。

最重要的步驟就是合併2個已經排序的序列。例如:a和b都是從小到大排序的序列。依次對比a的第乙個元素和b的第乙個元素,把其中較小的元素出序列,插入到c中,直到兩個序列中的元素都為空。最後,c序列就是乙個包含a序列和b序列且從小到排序的序列。

偽碼:    

1

merge(a,p,q,r)

2 n1 = q - p + 1

3 n2 = r -q

4 let l[1..n1 + 1] and r[1.. n2 + 1] be new

arrays

5for i = 1

to n1

6 l[i] = a[p + i - 1]7

for j = 1

to n2

8 r[i] = a[q +j]

9 l[n1 + 1] =∞

10 r[n2 + 1] =∞

11 i = 1

12 j = 1

13for k =p to r

14if l[i] <=r[j]

15 a[k] =l[i]

16 i = i + 1

17else

18 a[k] =r[i]

19 j = j + 1

view code

上述偽碼中,其中a為待排序的陣列,且a[p..q ]和a[q + 1..r]都是排序好的。9,10行中,在l,r最後插入乙個值,作為哨兵值,每當出現哨兵值時,它不可能為較小的值,這樣可以簡化**,避免檢查l或r為空。

圖例:

最後我們使用merge_sort 排序陣列a[p...r]中的元素。若p >= r,時,陣列中最多只有乙個元素,所以是排序好的,程式結束;否則,分解陣列a[p...r]為兩個子陣列a[p...q]和a[q + 1...r],然後合併2個子陣列。

偽碼:   

1

merge_sort(a,p,r)

2if p

3 q = ⌊(p + r) / 2⌋4

merge_sort(a,p,q)

5 merge_sort(a,q + 1

,r)6 merge(a,p,q,r)

view code

圖例:

歸併排序的時間複雜度:t(n) = o(nlgn)

c++**:

1

void merge(int a,int p,int q,intr)2

11for(int i = 0;i < n2;i++)

1215

16for(int k = p,il = 0,ir = 0; k <= r;k++)

1731

else

3237}38

}39 delete (l -n1);

40 delete (r -n2);41}

4243

//合併排序,t(n) = o(nlgn)

44void merge_sort(int a,int p,int

r)45

53 }

view code

排序演算法 歸併排序

歸併排序是建立在歸併操作上的一種有效的排序演算法。該演算法是採用分治法 divide and conquer 的乙個非常典型的應用。首先考慮下如何將將二個有序數列合併。這個非常簡單,只要從比較二個數列的第乙個數,誰小就先取誰,取了後就在對應數列中刪除這個數。然後再進行比較,如果有數列為空,那直接將另...

排序演算法 歸併排序

include include define status int define max 20 typedef struct elemtype typedef struct sqlist void inital sqlist l 初始化 bool lt int i,int j void merge ...

排序演算法 歸併排序

歸併排序的思想其實完全是分治法的思想的體現,它完全遵循分治法的模式。這裡有必要再重提下分治法的思想 將原有的問題分解為幾個規模較小的但類似於原問題的子問題,遞迴的求解這些子問題,然後再合併這些子問題的解來求得原問題的解。現在來看看歸併排序的操作 1 將等待排序的含有 n 個元素的序列分解成各具有 n...