從零開書學演算法(導論)之歸併排序

Morizen發表於2017-10-24

歸併排序思想為將序列每相鄰兩個數字進行歸併操作(merge),形成floor(n/2)個序列,排序後每個序列包含兩個元素將上述序列再次歸併,形成floor(n/4)個序列,每個序列包含四個元素重複步驟2,直到所有元素排序完畢。

下列程式碼為單次歸併的函式,可作為模板用於程式碼中。

PS:其中前段為第p位到第q位,後段為第q+1位到第r位。

void Merge(int p,int q,int r){
    int n1 = q - p + 1;
    int n2 = r - q;
    long long L[n1],R[n2];
    for(int i = 0;i < n1;i++) L[i] = A[i+p];
    for(int i = 0;i < n2;i++) R[i] = A[i+q+1];
    L[n1] = 100000000;R[n2] = 100000000;
    int i = 0;int j = 0;
    for(int k = p;k <= r;k++){
            if(L[i] < R[j]) A[k] = L[i++];
            else A[k] = R[j++];
    }
}

加上完整的排序程式碼如下

void Merge(int p,int q,int r)
{
	int n1 = q - p + 1;
	int n2 = r - q;
	long long L[n1],R[n2];
	//將原數列分到兩個數列
	for(int i = 0;i < n1;i++) L[i] = A[i+p];
	for(int i = 0;i < n2;i++) R[i] = A[i+q+1];
	L[n1] = 100000000;R[n2] = 100000000;//作為哨兵
	int i = 0;int j = 0;
	//接下來進行排序
	for(int k = p;k <= r;k++){
			if(L[i] < R[j]) A[k] = L[i++];
			else A[k] = R[j++];
	}
}
void Merge_sort(int p,int q)
{
	int l;
	if(p - q == 1) {
			if(A[q] < A[p]){l = A[q];A[q] = A[p];A[p] = l;}}
	else if(q - p) {
			int center = (p + q) / 2;
			Merge_sort(p,center);
			Merge_sort(center + 1,q);
			Merge(p,center,q);
	}
}


相關文章