排序演算法 歸併排序的時間複雜度分析

2021-09-26 10:19:34 字數 2375 閱讀 1603

歸併排序,其實就是遞迴+合併。

歸併排序將陣列取中間分為兩部分,兩個子陣列分別各自再從中間分為兩個子陣列,一直分下去直到不能再分。分完之後,再按照子陣列大小合併為為乙個有序陣列,然後層層向上合併,直到合併為乙個有序的陣列。

文字描述不理解的話,使用一副圖來解釋下:

其實歸併排序的思想很簡單,圖中也描述的很清楚。

歸併排序的時間複雜度為o(nlogn),跟冒泡、選擇、插入這三種排序o(n^2)的時間複雜度不同,要有效率很多。

我們把**呈上:

/**

* 歸併排序

* @param arr

* @param n

*/public static void mergesort(int arr,int n)

/*** 遞迴程式

* @param arr

* @param p

* @param r**/

public static void mergesort(int arr,int p,int r)

int q = (p+r)/2;

mergesort(arr,p,q);

mergesort(arr,q+1,r);

//合併

merge(arr,p,q,r);

}/**

* 合併

* @param arr

* @param p

* @param q

* @param r

*/public static void merge(int arr,int p,int q,int r)else

}//判斷arr(p,q)和arr(q+1,r)哪個有剩餘的資料

int start=i,end=q;

if(j<=r)

//將剩餘資料拷貝到臨時陣列temp中

while(start <= end)

//將temp中的資料拷貝回arr(p,r)陣列中

for (int l = 0; l <= r-p; l++)

}

歸併排序使用的是分治思想,分治思想簡單說就是分而治之,將乙個大問題分解為小問題,將小問題解答後合併為大問題的答案。乍一看跟遞迴思想很像,確實如此,分治思想一般就是使用遞迴來實現的。

需要說明的是,遞迴是**實現,分治思想是解決問題的方**,屬於理論層面的

其實mergesort這個函式就是使用遞迴層層分解問題的。可以看到將陣列的大區間[p,r]從中間分開,分成兩個小區間[p,q]和[q+1,r]

/**

* 遞迴程式

* @param arr

* @param p

* @param r**/

public static void mergesort(int arr,int p,int r)

int q = (p+r)/2;

mergesort(arr,p,q);

mergesort(arr,q+1,r);

//合併

merge(arr,p,q,r);

}

層層分解,直到滿足遞迴終止條件:p>=r,就說明分到最後1個不能再分了。既然無法再分,那接著就進行合併了。看起來merge函式寫的很複雜,其實如果理解了思想就非常容易理解了,千萬不能被嚇到。一切反動派都是紙老虎!

不是原地演算法,歸併排序在合併函式中使用到了temp臨時陣列用來存放[p,r]區間元素,這個臨時儲存空間在merge函式結束後就釋放了,所以歸併排序的空間複雜度保持在o(n).

歸併排序到底是不是穩定排序演算法,關鍵在合併的時候,合併的時候可以選擇對兩個區間中相等的元素,取[p,q]的元素先放入temp陣列中,保證了等值元素合併前後的存放順序。所以歸併排序是穩定排序演算法。

假如n個元素使用歸併排序的時間複雜度為t(n),那麼由於歸併排序使用的是分治思想,t(n)=2*t(n/2)+n,其中n就是兩個子區間合併的時間複雜度,這個從合併函式可以看出來。可以推導出以下公式:

t(1) = c;   n=1 時,只需要常量級的執行時間,所以表示為 c。

t(n) = 2*t(n/2) + n; n>1

經過進一步推導,可以得到t(n)=2^k * t(n/2^k) + k * n,我們假設t(1)=t(n/2^k),也就是說當n/2^k個元素的進行歸併排序,達到遞迴終止條件時,n/2^k=1,得到:k=logn

於是:t(n)=cn+nlog2n

歸併排序的時間複雜度就是o(nlogn),跟陣列的有序度其實並沒有什麼關係,是非常穩定的時間複雜度。

歸併排序演算法的時間複雜度

來自教程 我們對n個元素進行歸併排序,需要時間t n 那分解成兩個子陣列排序的時間都是t n 2 merge 函式合併的時間複雜度是o n 歸併排序的時間複雜度計算公式是 t 1 c n 1 時,只需要常量級的執行時間,所以表示為 c。t n 2 t n 2 n n 1 如何求t n 我們對t n ...

排序演算法之 歸併排序及時間複雜度分析

歸併排序 歸併排序是建立在歸併操作上的一種有效排序演算法,該演算法是採用分治法的乙個典型應用。這裡的分治如何理解?比如我們要統計本縣城的高考狀元,而乙個縣城中有很多中學,每個中學又有若干個班級,每個班級有若干名學生,每個學生是乙個單獨個體,看成陣列中的乙個元素。接下來,班級內學生兩兩組合併排好序組成...

歸併排序時間複雜度分析

主要參考了他的博文,他還講解了其他排序的時間複雜度分析及演算法實現。可以說合併排序是比較複雜的排序,特別是對於不了解分治法基本思想的同學來說可能難以理解。總時間 分解時間 解決問題時間 合併時間。分解時間就是把乙個待排序序列分解成兩序列,時間為一常數,時間複雜度o 1 解決問題時間是兩個遞迴式,把乙...