#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void
merge(int n1,const int a1[],int n2,const int a2[],int out[]) {
int i1;
int i2;
int iout;
i1=i2=iout=0;
while(i1 < n1 || i2 < n2) {
if(i2 >= n2 || ((i1 < n2) && (a1[i1] < a2[i2]))) {
out[iout++] = a1[i1++];
}
else {
out[iout++] = a2[i2++];
}
}
}
void
mergeSort(int n,const int a[],int out) {
int *a1;
int *a2;
int i ;
if(n<2) {
memcpy(out , a, sizeof(int)*n);
} else {
a1 = malloc(sizeof(int)*(n/2));
a2 = malloc(sizeof(int)*(n-n/2));
mergeSort(n/2,a,a1);
mergeSort(n-n/2,a+n/2,a2);
merge(n/2,a1,n-n/2,a2,out);
free(a1);
free(a2);
}
}
#define N (3)
int
main(int argc,char **argv) {
int a[N];
int b[N];
int i;
for(i = 0; i < N; i++) {
a[i] = N-i-1;
}
for(i = 0; i < N; i++) {
printf("%d ",a[i]);
}
putchar('\n');
mergeSort(N,a,b);
for(i = 0; i < N; i++) {
printf("%d ",b[i]);
}
putchar('\n');
return 0;
}
归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(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]。
我的博客-比较几种基本排序
归并排序的思想就是分治
和归纳
. 一个有序数组和另外一个有序数组合并, 那么还是一个有序数组, 这个叫merge
; 然后一个无序数组就变成一个有序数组的过程, 就是分治, 把无序数组递归的分治成若干个小数组(甚至是1个元素的数组), 变成排序的数组, 然后再进行归纳的过程.
弄懂思想的话, 代码应该还是很好理解和编写的吧