1.分解:分解待排序的 n n n个元素的序列成各具 n / 2 n/2 n/2个元素的俩哥哥子序列
2.解决:使用归并排序递归的排序两个子序列
3.合并:合并两个已排序的子序列得到答案
先考虑将两个已排序好的数组合并为一个数组
伪代码如下:
MERGE(A, p, q, r) //合并数组A[p..q],A[q+1..r]
n1 = q - p + 1
n2 = r - q
let L[1..n1+1] and R[1..n2+1] be new array
for i = 1 to n1
L[i] = A[p+i-1]
for j = 1 to n2
R[j] = A[q+j-1]
L[n1+1] = INFINITY //设置哨兵元素
R[n2+1] = INFINITY //设置哨兵元素
i = j = 1
for k = p to r
if L[i] <= R[j]
A[k] = L[i]
i = i + 1
else
A[k] = R[j]
j = j + 1
将MERGE作为归并排序的一个子程序调用,下面的过程MERGE_SORT,排序子数组 A [ p . . r ] A[p..r] A[p..r]中的元素。若 p ≥ r p \geq r p≥r, 则该子数组最多有一个元素,则已经排好序,否则,分解步骤简单的计算一个下标 q q q ,将 A [ p , r ] A[p, r] A[p,r] 分成两个子数组 A [ p , q ] A[p, q] A[p,q] 和 A [ q + 1 , r ] A[q+1, r] A[q+1,r] ,前者包含 ⌈ n / 2 ⌉ \lceil n/2 \rceil ⌈n/2⌉个元素,后者包含 ⌊ n / 2 ⌋ \lfloor n / 2 \rfloor ⌊n/2⌋个元素
伪代码如下:
MERGE_SORT(A, p, r)
if p < r
q = (p + r) / 2
MERGE_SORT(A, p, q)
MERGE_SORT(A, q+1, r)
MERGE(A, p, q, r)
#include
void Merge(int A[], int p, int q, int r) {
int n1, n2, i, j, k;
n1 = q - p + 1;
n2 = r - q;
int L[n1+1], R[n2+1];
for(i = 0; i < n1; i++) {
L[i] = A[p+i];
}
for(j = 0; j < n2; j++) {
R[j] = A[q+1+j];
}
L[n1] = 100000007;
R[n2] = 100000007;
i = j = 0;
for(k = p; k <= r; k++) {
if(L[i] <= R[j]) {
A[k] = L[i];
i++;
}
else{
A[k] = R[j];
j++;
}
}
}
void Merge_sort(int A[], int p, int r){
if(p < r) {
int q = (p + r) / 2;
Merge_sort(A, p, q);
Merge_sort(A, q+1, r);
Merge(A, p, q, r);
}
}
int main(){
int A[10] = {0, 5, 7, 6, 485, 48, 15, 49, 83, 464};
Merge_sort(A, 0, 9);
int i;
for(i = 0; i < 10; i++) {
printf("%d ", A[i]);
}
}