排序算法之歸併排序(Mergesort)解析

  轉自:http://www.cnblogs.com/ayqy/p/4050452.htmlhtml

 

一.歸併排序的優缺點(pros and cons)算法

耗費心思來理解它,總要有個理由吧:數組

  • 歸併排序的效率達到了巔峯:時間複雜度爲O(nlogn),這是基於比較的排序算法所能達到的最高境界
  • 歸併排序是一種穩定的算法(即在排序過程當中大小相同的元素可以保持排序前的順序,3212升序排序結果是1223,排序先後兩個2的順序不變),這一點在某些場景下相當重要
  • 歸併排序是最經常使用的外部排序方法(當待排序的記錄放在外存上,內存裝不下所有數據時,歸併排序仍然適用,固然歸併排序一樣適用於內部排序...)

缺點:post

  • 歸併排序須要O(n)的輔助空間,而與之效率相同的快排和堆排分別須要O(logn)和O(1)的輔助空間,在同類算法中歸併排序的空間複雜度略高

P.S.本文只討論最原始的「兩路歸併」,多路的與之相似3d

二.內部原理指針

首先要知道歸併排序的思想是:分治法,與快速排序的思想同樣htm

算法思想:無序 ->  部分有序  ->  總體有序blog

歸併排序中「分」與「合」的過程是結合在一塊兒的,即每一趟都在作「分」與「合」的工做,並非先「分」完再「合」(「分」很簡單,不就是一直二分二分直到不可再分唄,額,這麼想就錯了,分完就合不起來了,切記「分」與「合」是結合在一塊兒的)排序

用一幅圖來解釋歸併排序的過程就足夠了:遞歸

說明:P1與P2比較,將較大(小)者裝入P,而後P1或者P2右移(裝了誰就移誰),最後P右移

好比要對數組a[n]作升序排序,那麼具體過程以下:

  1. 申請兩個長度都爲n/2的輔助空間,把a數組裝進去,前一半裝進L,後一半裝進R
  2. 按照說明中的方式作一輪比較(P從A移動到C,一趟結束)

如今想一想咱們作完一趟排序獲得了什麼?

  1. 達成了部分有序(前一半 < 後一半,對吧?)
  2. 除此以外,咱們很天然的把待排序序列一分爲二,爲遞歸作好了準備

還不夠清晰?那麼還有幾句話:

  1. 圖示的過程解釋了爲何須要長度爲n的輔助空間
  2. 只要L和R各自內部都有序(同升序或者同降序),那麼只須要再通過一趟歸併,排序就完成了(仔細想一想,沒錯吧?)
  3. 排序部分就是合併部分(還記得上面提過的那句話嗎?「分」與「合」的過程是結合在一塊兒的,千萬不能分開想,不然你會發現合不起來了...)

三.實現細節

若是上面的解釋還不夠清晰,那麼咱們來舉個例子,一步步分析:

假定待排序序列爲a[] = {3, 2, 1, 4},那麼具體過程是這樣的:

P.S.若是待排序序列是奇數個怎麼辦?這是問題嗎?無非是拆得的前一半比後一半少一個而已,單趟循環控制是由P指針來作的,不存在某個P1沒有與之配對的P2能夠比的問題

四.總結

歸併排序多用於須要外部排序的場景,除此以外當內部排序須要保證穩定性時也採用歸併排序(不要求穩定性的內部排序通常採用快排或者堆排序,前者在待排序序列基本有序時效率低,後者堆的維護是個問題)

相關文章
相關標籤/搜索