1. 程式人生 > >歸併排序詳解

歸併排序詳解

歸併排序的想法其實是比較簡單的,但是實現起來卻並沒有那麼容易。現在我們思考如可將兩個區域性有序的兩個陣列組合成一個有序的序列,我們有An,Bn兩個序列且區域性有序,首先我們要新開闢一個新的陣列空間Cn。然後我們從An,Bn兩個序列中依次選取合適的元素加入Cn,我們要用兩個變數來標記An,Bn的下標,虛擬碼如下:
for (…)
{
if(A[i] > B[j])
{
C[k] = A[i];
i++;
}
else
{
C[k] = B[j];
j++;
}
if (A有剩餘)
{將A剩餘的元素加入C};
else
{將B剩餘的元素加入C};
}
我們思考這個的時候是不是可以想象到歸併演算法的思想了呢,就是將有序的多個歸併成一個,可能會有同學問,可是我們只有一個呀,這就是演算法的另一個要點:分裂,我們要利用遞迴先區域性有序,然後實現整體有序。
演算法實現圖解:
在這裡插入圖片描述

我們接下來看一下程式碼:
歸併排序:

void Merge (Sqlist L,Sqlist &L1,int left,int right,int mid)  //注意這裡的引用加在了目的陣列的後面;
{
	int i,j,k;
	for (i = left,j = mid + 1,k = left;i <= mid && j<= right;k++)
	{
		if (L.elem[i].data < L.elem[j].data)
			L1.elem[k] = L.elem[i++];
		else if (L.elem[i].data >=
L.elem[j].data) L1.elem[k] = L.elem[j++]; } //注意這裡的雖然i或j不滿足條件了,但是k++會執行最後一次!!!!! if (i <= mid) while (i <= mid) L1.elem[k++] = L.elem[i++]; if (j <= right) while (j <= right) L1.elem[k++] = L.elem[j++]; } void Msort(Sqlist L,Sqlist &LT,int left,int right) //同樣注意這裡的引用位置!!
{ int mid; Sqlist L2; L2.elem = new Elementype[N];//開闢新的陣列空間; if (left == right) LT.elem[left] = L.elem[left]; else { mid = (left + right) / 2; //找到分裂點 Msort(L,L2,left,mid); //分裂點左側進行歸併排序 Msort(L,L2,mid + 1,right);//分裂點右側進行歸併排序 Merge(L2,LT,left,right,mid)//將以排序的兩組進行歸併 } } void Merge_sort(Sqlist &L) { Msort(L,L,1,L.length); }

演算法在用的過程中從新生成了一個數組,所以資料轉移的路徑大概如下:
L------>L2-------->L;
歸併演算法在考研中不要求程式碼級別,但是我們還要以掌握程式碼為目標!!!