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

2021-07-15 03:23:44 字數 2311 閱讀 2442

本文主要介紹歸併排序的基本原理,基於遞迴呼叫,一步一步分析,結合流程圖和文字,給讀者清晰地解釋。另外給出偽**,和c++核心**。並和插入排序相比較,最後結合插入排序,介紹一種公升級的歸併排序。

歸併排序利用分治法的思想,具體演算法框架如下:

step1: 將待排序列 a 分為兩個子串行,再將子串行一分為二,一直分到每個子串行只含有乙個元素為止,這個時候,每個子串行(都只包含乙個元素)已經是有序的。

step2: 根據分解的路徑,對每一對子串行進行排序

step3: 將已經排序的兩個子串行合併,最後合成整個序列。

分解示意圖:

合併示意圖:

具體的合併方式為:將兩個已經排好序的子串行合併為乙個新的長序列。從左到右,依次瀏覽兩個待合併序列的第乙個元素,將較小的元素移入到新序列中,當其中乙個序列全部排到新序列裡,則將另乙個序列直接複製到新序列的末尾

兩個子串行合併的偽**如下:

整個歸併排序是乙個遞迴過程,不斷解決規模較小的子問題,然後將這些子問題的解合併得到原問題的解。偽**如下。

本文給出的例項,遞迴呼叫步驟:

}if (loc < high) // 沒有排滿

}else}}

}void mergesort(vector

& vec, int low, int high)

}由於將兩個子陣列合併成長度為 n 的子陣列需要的時間為 θ(

n),根據合併示意圖,假設序列長度為

n ,則遞迴呼叫 merge 函式的級數為 ⌈l

og2(

n)⌉向上取整,所以總的時間代價為 θ(

nlog

2(n)

) θ(

n2) ,歸併排序優於插入排序。

由於歸併排序在歸併過程中需要與原始記錄序列相等的儲存空間,另外遞迴呼叫時需要深度為⌈l

og2(

n)⌉ 的棧空間,因此空間複雜度為c1

∗n+c

2∗⌈l

og2(

n)⌉ ,其中 c1

,c2 為與系統相干的常數。即空間複雜度為o(

n)。而插入排序不需要建立待排序列的副本,即不需要額外的儲存空間,因此,在空間複雜度方面,插入排序佔優勢。

根據合併的具體操作,當兩個數相等時,它們的相對位置不會改變,因此歸併排序具有穩定性。

由於當

n 較小時,n2

和 log

2n相差不大,為了減小遞迴呼叫的開銷,當子串行減小到一定的規模時,可以使插入排序,然後將插入排序後的兩個子串行合併。

具體c++**如下:

void insertsort1(vector

&vec,int low,int high)

vec[j + 1] = insertvalue;

}}//當子串行的長度小於或等於 n0 時用插入排序

void mergesort1(vector

& vec, int low, int high, int n0)

else

}

插入排序,歸併排序,公升級版歸併排序 分別用執行時間比較:

輸入序列為 10000 點的隨機序列, 當子串行長度小於等於 n0

=64時, 用插入排序。

由此可見,歸併排序的時間遠遠小於插入排序,主要原因由於插入排序需要大量的元素搬移操作,而且公升級版的歸併排序略好於普通版的歸併排序。

經典演算法 歸併排序

題目說明 歸併排序是建立在歸併操作上的一種有效的排序演算法。該演算法也是採用分治法 divide and conquer 的乙個非常典型的應用。演算法複雜度為o n logn 題目解析 歸併排序是利用遞迴和分而治之的技術將資料序列劃分成為越來越小的半子表,再對半子表排序,最後再用遞迴步驟將排好序的半...

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

1 思想 多次將兩個或兩個以上的有序表合併成乙個新的有序表。2 演算法時間複雜度 最好的情況下 一趟歸併需要n次,總共需要logn次,因此為o n logn 最壞的情況下,接近於平均情況下,為o n logn 說明 對長度為n的檔案,需進行logn 趟二路歸併,每趟歸併的時間為o n 故其時間複雜度...

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

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