將乙個大序列的排序問題分解為對兩個或多個子串行的排序問題,然後對子序列遞迴使用同樣的方式進行排序;在子串行排好序後,將結果合併起來即可。利用這種思想的排序方法就是著名的歸併排序。之所以稱為歸併排序,是因為整個演算法的成本由歸併部分決定。
歸併演算法描述如下:
1)如果n=1,排序完成;
2)將序列分解為兩個子串行a[1 …ceiling(n/2)]和a[ceiling(n/2)+1 …n];
3)遞迴對子序列a[1 …ceiling(n/2)]和a[ceiling(n/2)+1 …n]進行排序;
4)將排好序的兩個子串行進行歸併。
歸併排序使用的是分治策略,而分治策略的關鍵是分解和合併。歸併排序的分解很簡單:直接將序列從中間斬斷;但合併的時候需要將兩個排好序的子串行按次序進行合適的穿插,從而獲得原序列的乙個排序。
合併時我們使用兩個指標:乙個指向a序列裡下乙個要歸併的元素,乙個指向b序列裡下乙個要歸併的元素。每步我們對這兩個指標所指的元素進行比較,小者被歸併到c序列裡,並將指向較小者的指標往後推進乙個元素,另乙個指標保持不動。這樣迴圈往復直到乙個子串行為空。這時,另乙個子串行中剩下的所有元素直接複製到c序列末尾即可。
注意:歸併排序在最壞、平均和最好情況下時間複雜度都是θ(nlogn)
。這是歸併排序乙個顯著的特點:一視同仁。 /*
函式名:
mergesort
功能:歸併排序
模板引數說明:
t必須支援小於操作
引數說明:
data
待排序陣列
, size
待排序陣列大小
前置條件:
data!=null, size>0
後置條件:
data
按非降序排列
用法:#include
int arr=;
mergesort(arr, 10);
*/template
<
typename
t>
void
mergesort (t data,
intsize)}/*
函式名:
mergesort
功能:歸併排序
模板引數說明:
t元素型別
, func
函式物件或指標
引數說明:
data
待排序陣列
, size
待排序陣列大小
,f函式物件或指標
前置條件:
data!=null, size>0
後置條件:
data按f
排列用法:
#include
bool cmp(int a, int b)
;mergesort(arr, 10
,cmp);
*/template
<
typename
t, typename
func>
void
mergesort (t data,
intsize, func f)
}
演算法之歸併排序
歸併排序 void mergearray int a,int temp,int left,int mid,int right else while i1 mid while i2 right for int i 0 i k i 上面 為合併a left,mid 和a mid 1,right 的 因為...
演算法之歸併排序
歸併排序是分治法 divide and conquer 的經典案例。分治模式在每一層遞迴上都有三個步驟 分解 divide 將原問題分解成一系列子問題 解決 conquer 遞迴地解各子問題。若子問題足夠小,則直接求解 合併 combine 將子問題的結果合併成原問題的解。歸併排序 merge so...
排序演算法之歸併排序
歸併排序也是經典的使用分治法思想的代表演算法之一。歸併排序的效率很高,而且是一種穩定的排序。其總體的思想思路就是將待排序的元素分成大致相同的兩個子集合,分別對兩個子集合進行排序,最終將排序的子集合合併成排好序的總集合 歸併排序c 實現如下 include void mergesort int arr...