很多时候我们碰到的问题很复杂,一眼望去找不到解决的办法。但是对于解决小问题常常不在话下,那么有种思想就促使我们能不能把复杂的问题分解成一个个小问题加以解决最后再归并起来呢?也许分一步的结果仍不容易解决,我们就继续分解,直到分到最简单的问题为止。这种思想在我们生活中很常见,而在算法中,它其实是一种“分治策略”。
分治策略所引出的排序方法便是归并排序。
归并排序的思想是一分为二,递归求解。
1 文字表述:
输入一个数组A[p...r],要求给它的元素排序。
我们把数组先分成两组:A[p...q] 和 A[q+1...r]
2 伪码表示:
<span style="font-size:14px;">MERGE-SORT(A,p,r)
1 if p < r
2 q = 小于或等于(p+r)/2的最大整数
3 MERGE-SORT(A,p,q)
4 MERGE-SORT(A,q+1,r)
5 MERGE(A,p,q,r)</span>
<span style="font-size:14px;">MERGE(A,p,q,r)
1 n1 = (q - p) + 1 = q - p + 1
2 n2 = (r - (q + 1)) +1 = r - q
3 let L[1..n1+1] and R[1..n2+1] be new arrays
4 for i = 1 to n1
5 L[i] = A[p + i -1]
6 for j = 1 to n2
7 R[j] = A[q + j]
8 L[n1 + 1] = #
9 R[n2 + 1] = #
10 i = 1;
11 j = 1;
12 for k = p to r
13 if L[i] <= R[j]
14 A[k] = L[i];
15 i = i + 1;
16 else
17 A[k] = R[j]
18 j = j + 1;</span>
<span style="font-size:14px;">#include<stdio.h>
void merge_sort(int *A,int p,int r);
void merge(int *A,int p,int q,int r);
int main(){
int array[5];
int num;
printf("请输入数组长度:\n");
scanf("%d",&num);
printf("请输入元素:\n");
for(int i=0;i<num;i++)
scanf("%d",&array[i]);
merge_sort(array,0,num-1);
for(int i=0;i<num;i++)
printf("%d",array[i]);
return 0;
}
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);
}
}
void merge(int *A,int p,int q,int r){
int n1=q-p+1;
int n2=r-q;
int L[n1-1],R[n2-1];
for(int i=0;i<n1-1;i++)
L[i]=A[p+i];
for(int j=0;j<n2-1;j++)
R[j]=A[q-1+j];
int key=0;
L[n1]=key;
R[n2]=key;
int i=0,j=0;
for(int k=0;k<r-p;k++){
if(L[i]<=R[j]){
A[k]=L[i];
i++;
}
else{
A[k]=R[j];
j++;
}
}
}</span>