分治 歸併排序

2021-09-30 01:50:24 字數 2114 閱讀 3220

將兩個排序好的陣列歸併過程如下:

紅色的 1 是左邊起始位置;

綠色的 2 是右邊起始位置;

灰色的 最右邊 是右邊終點位置;

#include

using

namespace std;

typedef

int elementtype;

//l = 左邊起始位置, r = 右邊起始位置, rightend = 右邊終點位置

void

merge

(elementtype a[

], elementtype tmpa,

int l,

int r,

int rightend)

while

(l <= leftend)

//剩下的陣列全加上去

tmpa[i++

]= a[l++];

while

(r <= rightend)

//剩下的陣列全加上去

tmpa[i++

]= a[r++];

for(

int i =

0; i <= len; i++

,rightend--

) a[rightend]

= tmpa[rightend];}

void

msort

(elementtype a[

], elementtype tmpa,

int l,

int rightend)

//要排序的部分為 l 到 rightend

}void

merge_sort

(elementtype a,

int n)

//用堆申請記憶體排序完再 free 就不會浪費棧記憶體了

else

cout <<

"空間不足";}

intmain()

;int len =

sizeof

(a)/

sizeof

(a[0])

;merge_sort

(a, len)

;for

(int i =

0; i < len; i++

) cout << a[i]

<<

" ";

return0;

}

通過使用分治演算法的思想來對陣列進行排序(這裡叫做歸併排序),分治演算法的核心思想就是把乙個問題分解n個小問題,然後把這n個小問題分別解決,最後再把這n個小問題的結果合併便可以得到結果了。(分解–解決–合併)

此題思路是:

先將乙個未排列的陣列二分、二分、再二分,當分到只有乙個元素時再歸併,歸併就是將原來二分的兩個陣列合併成乙個,歸併的時候順便排序(歷遍兩個陣列排到乙個陣列上),重複此操作,二分多少次就歸併多少次,最後得到的就是乙個排好序陣列

對n個元素進行排序的時間複雜度:

t

(n)=2*

t(n/2)

+ a * n (a是常數,具體多少不重要)=2

*(2*

t(n/4)

+ a * n/2)

+a * n=4

*t(n/4)+

2a * n=4

*(2*

t(n/8)

+ a * n/4)

+2* a * n=8

*t(n/8)+

3* a * n……=

2k *

t(n/

2k)+ k * a * n

一直到n/

2k =

1(此時k = log2n)

t(n)

=2k *t(

1)+ k * a * n

=2k + k * a * n

= n + a *

(log2n)

* n故複雜度為 o

(n * logn)

歸併排序(分治)

把乙個陣列 a 分成兩個部分 s,m m 1,e 假設兩部分分別有序,把這兩部分合併到另一陣列中 tmp 保證該陣列有序,然後再把資料 e s 1拷貝回陣列a 分治的原理。把資料無限二分,最後比較兩個數即可。遞迴實現。includeusing namespace std int a 10 int b...

歸併排序 分治

歸併 將已有序的子串行合併,得到完全有序的序列 即先使每個子串行有 序,再使子串行段間有序。若將兩個有序表合併成乙個有序表,稱為二路歸併。歸併的本質 空間換時間,通過申請乙個額外陣列儲存中間變化,從而實現排序 歸併排序核心步驟 歸併排序的特性總結 歸併的缺點在於需要o n 的空間複雜度,歸併排序的思...

歸併排序 分治

在合併鍊錶的題目中,有乙個典型的題目 合併有序鍊錶 這道題的解法有很多,比較典型的解法是 分治法。這道題的題幹已經給出了重要的資訊 每乙個鍊錶的區域性是有序的。那麼,解決這道題時就可以利用這個特點,不用將每乙個元素逐個比較,可以將鍊錶兩兩排序合併。鍊錶兩兩排序合併有什麼好處?鍊錶兩兩排序可以降低比較...