經典排序演算法之 歸併排序

2021-06-20 15:21:57 字數 2516 閱讀 3965

1、思想:多次將兩個或兩個以上的有序表合併成乙個新的有序表。

2、演算法時間複雜度

最好的情況下:一趟歸併需要n次,總共需要logn次,因此為o(n*logn)

最壞的情況下,接近於平均情況下,為o(n*logn)

說明:對長度為n的檔案,需進行logn 趟二路歸併,每趟歸併的時間為o(n),故其時間複雜度無論是在最好情況下還是在最壞情況下均是o(nlgn)。 3、

穩定性

歸併排序最大的特色就是它是一種穩定的排序演算法。歸併過程中是不會改變元素的相對位置的。

4、缺點是,它需要o(n)的額外空間。但是很適合於多鍊錶排序。

例如:13579 2468這兩個序列,各自都是排好序的,然後我們進行合併,成為123456789這樣乙個

排好序的序列。貌似這個跟排序關係不大,因為排序給的是乙個亂的序列,而合併是合併的兩個已經排序

好的序列。且慢,我們可以把需要排序的資料分解成n個子序列,當分解的子串行所包含資料個數為1的時

候,那麼這個序列不久是有序了嗎?然後再合併。這個就是有名的」分治「了。例如321分成3,2,1三個序

列,1這個序列是有序的啦。。同理2,3都是有序的。然後我們逐一的合併他們。3,2合併為23,然後在

23與1合併為123。哈哈,排序成功。合併排序主要思路就是這樣了。但是,問題又出來了,怎麼合併兩

個有序列呢?我相信我應該理解了陣列的儲存方式,所以直接用陣列說事啦。。我們先把下標定位到各有

序子串行的開始,也把合併之後陣列的下標定位到最初。那麼下標對應的位置就是他們當前的最小值了。

然後拿他們來比較,把更小的那個放到合併之後陣列的下標位置。這樣,合併後陣列的第乙個元素就是他

們的最小值了。接著,控制合併後陣列的下標後移乙個,把比較時小數字所在序列對應的下標後移乙個。

這樣。下次比較的時候,他得到就是他的第二小,(第一下已經合併了)就是當前最小值了,在於另一

個序列的當前最小值比較,用小的乙個放到合併後陣列的相應位置。依次類推。接著當資料都合併玩了結

束,合併完成。

來做例子:

(1回合)    1357 2468 (合併後資料空)

(2)  357 2468 100000(0表示空) 因為1 < 2所以把1放到合併後位置中了(這裡1並不是丟掉了,而是下

標變為指向3了,1是沒有寫而已。呵呵。理解為陣列的下標指向了3)

(3) 357 468 120000  因為3 > 2,所以把而放進去

(4) 57 468  123000  同理3 < 4

(5) 57 68   1234000 同理5 > 4

(6) 7 68    1234500 同理5 > 6

(7) 7 8        1234560 同理7 > 6

(8) 0(空了) 8 12345670 同理7 < 8

(9) 0 0 12345678  弄最後乙個

當然,這些只是思路。並不是一定一成不變的這樣。合併ok,那麼我們就可以用合併排序了哦!哈哈。。

不過注意,那個321全部弄成乙個單個數字,然後乙個乙個合併這樣來合併似乎不是很好,貌似還有更好

的解決方案。哈哈,對了,就是我先分一半來合併。如果這一半是排好序的,那麼合併不久簡單了嗎?但

是我怎麼讓一般排好序呢。呵呵簡單,我一半在分一半合併排序,在分一半合併排序,直到分到兩個都是

1個了,就合併,ok!

例如,81726354:

(1)分成9172 6354

(2)把8172 分成 81 和72 把6354分成63和54

(3)81分成8和1,哦能合併了哦。合併為18, 同理72,63,54,也可以分解成單個合併為27,36,45

(4) 現在變為了 18, 27, 36, 45了,這個時侯,18 和27能合併了,合併為1278 同理36,合併為45 3456

(5) 好了最好吧,1278和3456合併為12345678.ok排序成功。哈哈。

這樣把乙個問題分解為兩個或多個小問題,然後在分解,最後解決小小問題,已達到解決大問題的目的。

思路主要就是這樣了哦:

程式實現上也有點技巧。這個就不說了,直接奉上源**:

#define infinite 1000  

//對兩個序列進行合併,陣列從mid分開

//對a[start...mid]和a[mid+1...end]進行合併

void merge(int *a,int start,int mid,int end)

else

} free(array1);

free(array2);

} //歸併排序

void mergesort(int *a,int start,int end)

{ int mid=(start+end)/2;

if(start

經典排序演算法之歸併排序

原理,把原始陣列分成若干子陣列,對每乙個子陣列進行排序,繼續把子陣列與子陣列合併,合併後仍然有序,直到全部合併完,形成有序的陣列 舉例無序陣列 6 2 4 1 5 9 先看一下每個步驟下的狀態,完了再看合併細節 第一步 6 2 4 1 5 9 原始狀態 第二步 2 6 1 4 5 9 兩兩合併排序,...

經典排序演算法之歸併排序

python實現 歸併排序演算法,a是陣列,n表示陣列大小 merge sort a,n 遞迴呼叫函式 merge sort c a,p,r 歸併排序 defmerge sort arr list int merger sort c arr,0,len arr 1 def merger sort c...

經典排序之歸併排序

package 歸併排序 歸併排序的思想 將陣列從中間分開,然後利用遞迴的方法將左右子串行均拆開 再借助乙個陣列歸併左右序列,排序是在歸併時進行的,最後將資料複製到原始陣列中 public class mergesort public static void main string args ret...