归并排序算法的基本思想是:将待排序元素分成大小大致相同的两个子集合,分别对两个子集合进行排序,最终将排好序的子集合合并成所要求的排好序的集合。
代码实现:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef int TYPE;
#define PRINT_FORMAT "%-3d "
#define ARR_LEN 100
int main(void) {
void get_random_arr(TYPE arr[], int len);
void print_arr(TYPE arr[], int len);
void merge_sort(TYPE arr[], int len);
TYPE arr[ARR_LEN];
get_random_arr(arr, ARR_LEN);
printf("Befor Sorting:\n");
print_arr(arr, ARR_LEN);
merge_sort(arr, ARR_LEN);
printf("After Sorting:\n");
print_arr(arr, ARR_LEN);
return EXIT_SUCCESS;
}
/*
** 归并排序
*/
void merge_sort(TYPE arr[], int len) {
void merge_pass(TYPE src[], TYPE dst[], int size, int len);
TYPE *arr_tmp;
int size = 1;
arr_tmp = (TYPE*) malloc(sizeof(int) * len);
if (arr_tmp == NULL) {
perror("malloc");
exit(EXIT_FAILURE);
}
while (size < len) {
merge_pass(arr, arr_tmp, size, len); // 合并到临时数组
size += size;
merge_pass(arr_tmp, arr, size, len); // 再合并回原数组
size += size;
}
free(arr_tmp);
}
/*
** 合并大小为size的相邻子数组
*/
void merge_pass(TYPE src[], TYPE dst[], int size, int len) {
void merge(TYPE src[], TYPE dst[], int r, int s, int t);
int i;
for (i = 0; i <= len - size*2; i += size*2) {
merge(src, dst, i, i+size-1, i+size*2-1);
}
/*
** 剩下的元素,个数小于2*size
*/
if (i + size < len) {
/*
** 剩下的元素,如果个数大于size,则再合并一次
*/
merge(src, dst, i, i+size-1, len-1);
} else {
/*
** 剩下的元素,如果个数不大于size,则直接复制过去
*/
while (i <= len-1) {
dst[i] = src[i];
i++;
}
}
}
/*
** 合并src[r:s]和src[s+1:t]到dst[r:t]中
*/
void merge(TYPE src[], TYPE dst[], int r, int s, int t) {
int i = r;
int j = s + 1;
int k = r;
while ( (i <= s && j <= t) ) {
if (src[i] <= src[j])
dst[k++] = src[i++];
else
dst[k++] = src[j++];
}
if (i > s) {
while (j <= t)
dst[k++] = src[j++];
} else {
while (i <= s)
dst[k++] = src[i++];
}
}
/*
** 简单地获取随机数组
*/
void get_random_arr(TYPE arr[], int len) {
int i;
srand((unsigned int)time(NULL));
for (i = 0; i < len; i++) {
arr[i] = rand() % 100;
}
}
/*
** 打印数组
*/
void print_arr(TYPE arr[], int len) {
int i;
for (i = 0; i < len; i++) {
printf(PRINT_FORMAT, arr[i]);
if ((i + 1) % 10 == 0)
putchar('\n');
}
putchar('\n');
}
结果输出:
Befor Sorting:
41 67 34 0 69 24 78 58 62 64
5 45 81 27 61 91 95 42 27 36
91 4 2 53 92 82 21 16 18 95
47 26 71 38 69 12 67 99 35 94
3 11 22 33 73 64 41 11 53 68
47 44 62 57 37 59 23 41 29 78
16 35 90 42 88 6 40 42 64 48
46 5 90 29 70 50 6 1 93 48
29 23 84 54 56 40 66 76 31 8
44 39 26 23 37 38 18 82 29 41
After Sorting:
0 1 2 3 4 5 5 6 6 8
11 11 12 16 16 18 18 21 22 23
23 23 24 26 26 27 27 29 29 29
29 31 33 34 35 35 36 37 37 38
38 39 40 40 41 41 41 41 42 42
42 44 44 45 46 47 47 48 48 50
53 53 54 56 57 58 59 61 62 62
64 64 64 66 67 67 68 69 69 70
71 73 76 78 78 81 82 82 84 88
90 90 91 91 92 93 94 95 95 99