书上讲的第二个算法是合并排序,采用了分治法的思想,合并法遵照了分治模式,在每一层递归上都有三个步骤:
分解:将n个元素分成各含n/2个元素的子序列
解决:用合并排序对两个子序列递归地排序
合并:合并两个已排序的子序列以得到排序的结果
在对子序列排序时,其长度为1时递归结束。单个元素被视为是已排好序的。
其C语言实现如下:
#include <stdio.h> #include <stdlib.h> #include <assert.h> #include <limits.h> void merge(int *A, unsigned int p, unsigned int q, unsigned int r) { unsigned int i, j, k; //前半段为A[p..q], 后半段为A[q+1..r] int *L = (int *)malloc((q - p + 1 + 1) * sizeof(int)); //q-p+1为前半段元素的个数,外加额外的一个哨兵 int *R = (int *)malloc((r - q + 1) * sizeof(int)); //r-q为后半段元素的个数,外加额外的一个哨兵 assert((L != NULL) && (R != NULL)); for (i = 0; i < q - p + 1; i++) { L[i] = A[p + i]; } for (j = 0; j < r - q; j++) { R[j] = A[q + 1 + j]; } L[q - p + 1] = INT_MAX; R[r - q] = INT_MAX; 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++; } } free(L); free(R); } void merge_sort(int *A, unsigned int p, unsigned int r) { if (p < r) { unsigned int q = (r + p) / 2; merge_sort(A, p, q); merge_sort(A, q + 1, r); merge(A, p, q, r); } } int main() { int array[] = {5, 10, 2, 3, 9, -1, 3}; int i; merge_sort(array, 0, sizeof(array) / sizeof(int) - 1); for (i = 0; i < sizeof(array) / sizeof(int); i++) { printf("%d ", array[i]); } return 0; }