歸併排序是建立在歸併操作上的一種有效的排序演算法,該演算法是採用分治法(divide and conquer)的乙個非常典型的應用。將已有序的子串行合併,得到完全有序的序列;即先使每個子串行有序,再使子串行段間有序。若將兩個有序表合併成乙個有序表,稱為二路歸併。
歸併過程為:比較a[i]和a[j]的大小,若a[i]≤a[j],則將第乙個有序表中的元素a[i]複製到r[k]中,並令i和k分別加上1;否則將第二個有序表中的元素a[j]複製到r[k]中,並令j和k分別加上1,如此迴圈下去,直到其中乙個有序表取完,然後再將另乙個有序表中剩餘的元素複製到r中從下標k到下標t的單元。歸併排序的演算法我們通常用遞迴實現,先把待排序區間[s,t]以中點二分,接著把左邊子區間排序,再把右邊子區間排序,最後把左區間和右區間用一次歸併操作合併成有序的區間[s,t]。
歸併排序主要分為兩部分:
1、劃分子區間
2、合併子區間
現在以 9,6,7,22,20,33,16,20 為例講解上面兩個過程:
第一步,劃分子區間:每次遞迴的從中間把資料劃分為左區間和右區間。原始區間為[start,end],start=0,end=[length-1],減一是因為陣列的下標從0開始,本例中length=8,end=7.現在從中間元素劃分,劃分之後的左右區間分別為 [start,(end-start+1)/2+start],右區間為[(end-start+1)/2+start+1,end],本例中把start和end帶入可以得到[0,7],劃分後的左右子區間為[0,4],[5,7],然後分別對[start,end]=[0,4]和[start,end]=[5,7]重複上一步過程,直到每個子區間只有乙個或者兩個元素。整個分解過程為:
子區間劃分好以後,分別對左右子區間進行排序,排好序之後,在遞迴的把左右子區間進行合併,整個過程如下圖所示:
現在看**:
void merge_sort(int *data, int start, int end, int *result)
return;
}else
if(0 == end - start)//如果只有乙個元素,則不用排序
return;
else
}
merge的過程為:
void merge(int *data,int start,int end,int *result)
while(left_index < start + left_length)
result[result_index++] = data[left_index++];
while(right_index < end+1)
result[result_index++] = data[right_index++];
}
現在對程式進行測試:
int main()
; const
int length = 8;
int result[length];
cout
<< "before sorted:"
<< endl;
for(int i = 0;i < length;++i)
cout
<< data[i] << " ";
cout
<< endl;
cout
<< "after sorted:"
<< endl;
merge_sort(data,0,length-1,result);
for(int i = 0;i < length;++i)
cout
<< data[i] << " ";
cout
<< endl;
return
0;}
程式執行結果如下:
歸併排序 C 實現
歸併排序跟快速排序一樣,也是基於 分治法 歸併排序與快速排序的區別 快速排序是先 分治 成兩個子串行,然後呼叫本身繼續遞迴進行 分治 歸併排序是先遞迴地分成子串行,然後按演算法合併。歸併排序是先遞迴地把待排序序列分成若干子串行,直到最後分成乙個乙個元素為子串行,然後對些子串行中每個元素,依照其大小合...
C 實現歸併排序
歸併 歸併排序 merge sort 是建立在歸併操作上的一種有效的排序演算法,該演算法是採用分治法 divide and conquer 的乙個非常典型的應用。將已有序的子串行合併,得到完全有序的序列 即先使每個子串行有序,再使子串行段間有序。若將兩個有序表合併成乙個有序表,稱為二路歸併。演算法描...
C 歸併排序實現
基本過程 採用分治的核心思想,把乙個複雜問題拆成若干子問題求解。通過遞迴的方法,不斷對左右兩部分進行拆分 比較左右兩部分大小,不斷將左右兩部分按順序合併 實現 include include using namespace std void merge vector int nums,int low...