这文档是根据《算法导论》第2版的伪代码用C语言写的代码,因为用到了c99的一些特性,如变长数组。需要用gcc指定选项-std=c99编译,不支持VC。
参考书:
算法导论第2版电子版:
http://www.kuaipan.cn/file/id_12008874588516081.html
C语言程序设计_现代方法(第2版)电子版:
http://www.kuaipan.cn/file/id_12008874588516159.html
By 小鹏,QQ:562453464
2011.11.30
#include <stdio.h> #include <string.h> #include <time.h> #include <stdlib.h> void insertion_sort(void *base, size_t elem_size, size_t n, int (*comp) (const void *, const void *)) { char *cbase = base; char key[elem_size]; for (size_t i = 1; i < n; i++) { memcpy(key, &cbase[i * elem_size], elem_size); /*把base[i]插入到排好序的base[0..i-1]中 */ int j = i - 1; while (j >= 0 && comp(&cbase[j * elem_size], key) > 0) { memcpy(&cbase[(j + 1) * elem_size], &cbase[j * elem_size], elem_size); j--; } memcpy(&cbase[(j + 1) * elem_size], key, elem_size); } } void swap(void *a, void *b, size_t elem_size) { if(a==NULL||b==NULL||a==b) return; char temp[elem_size]; /*变长数组 */ memcpy(temp, a, elem_size); memcpy(a, b, elem_size); memcpy(b, temp, elem_size); } void randomized_in_place(void *array, size_t elem_size, int n) { char *carray = array; for (int i = 0; i < n; i++) { int index = rand() % (n - i) + i; swap(&carray[i * elem_size], &carray[index * elem_size], elem_size); } } void print_array(int a[], int n) { for (int i = 0; i < n; i++) { printf("%d ", a[i]); } printf("\n"); } int cmp_int(const void *p1, const void *p2) { const int *pa = p1; const int *pb = p2; if (*pa < *pb) return -1; if (*pa == *pb) return 0; return 1; } int main(void) { srand((unsigned)time(NULL)); int a[10]; for (int i = 0; i < 10; i++) { a[i] = i; } randomized_in_place(a, sizeof(int), 10); printf("排序前:\n"); print_array(a, 10); insertion_sort(a, sizeof(int), 10, cmp_int); printf("排序后:\n"); print_array(a, 10); return 0; }
#include <stdio.h> #include <limits.h> #include <stdlib.h> #include <string.h> #include <time.h> void merge(void *base, size_t elem_size, size_t left, size_t middle, size_t right, void *max, int (*comp) (const void *, const void *), void *buff) { char *cbase = base; char *cbuff = buff; size_t left_length = middle - left + 1; size_t right_length = right - middle; char *left_buff = cbuff; char *right_buff = &cbuff[(left_length + 1) * elem_size]; for (size_t i = 0; i < left_length; i++) { memcpy(&left_buff[i * elem_size], &cbase[(left + i) * elem_size], elem_size); } memcpy(&left_buff[left_length * elem_size], max, elem_size); for (size_t i = 0; i < right_length; i++) { memcpy(&right_buff[i * elem_size], &cbase[(middle + 1 + i) * elem_size], elem_size); } memcpy(&right_buff[right_length * elem_size], max, elem_size); for (size_t k = left, i = 0, j = 0; k <= right; k++) { if (comp(&left_buff[i * elem_size], &right_buff[j * elem_size]) <= 0) { memcpy(&cbase[k * elem_size], &left_buff[i * elem_size], elem_size); i++; } else { memcpy(&cbase[k * elem_size], &right_buff[j * elem_size], elem_size); j++; } } } void merge_sort_buff(void *base, size_t elem_size, size_t left, size_t right, void *max, int (*comp) (const void *, const void *), void *buff) { if (left < right) { size_t middle = (left + right) / 2; merge_sort_buff(base, elem_size, left, middle, max, comp, buff); merge_sort_buff(base, elem_size, middle + 1, right, max, comp, buff); merge(base, elem_size, left, middle, right, max, comp, buff); } } void merge_sort(void *base, size_t elem_size, size_t left, size_t right, void *max, int (*comp) (const void *, const void *)) { if (left >= right) return; size_t length = right - left + 1; /*数组的长度 */ char buff[(length + 2) * elem_size]; /*+2是因为要在缓存保存两个最大值 */ merge_sort_buff(base, elem_size, left, right, max, comp, buff); } void swap(void *a, void *b, size_t elem_size) { if(a==NULL||b==NULL||a==b) return; char temp[elem_size]; /*变长数组 */ memcpy(temp, a, elem_size); memcpy(a, b, elem_size); memcpy(b, temp, elem_size); } void randomized_in_place(void *array, size_t elem_size, int n) { char *c_array = array; for (int i = 0; i < n; i++) { int index = rand() % (n - i) + i; swap(&c_array[i * elem_size], &c_array[index * elem_size], elem_size); } } void print_array(int a[], int n) { for (int i = 0; i < n; i++) { printf("%d ", a[i]); } printf("\n"); } int cmp_int(const void *p1, const void *p2) { const int *pa = p1; const int *pb = p2; if (*pa < *pb) return -1; if (*pa == *pb) return 0; return 1; } int main(void) { srand((unsigned)time(NULL)); int a[10]; for (int i = 0; i < 10; i++) { a[i] = i; } randomized_in_place(a, sizeof(int), 10); printf("排序前:\n"); print_array(a, 10); int max_int = INT_MAX; merge_sort(a, sizeof(int), 0, 9, &max_int, cmp_int); printf("排序后:\n"); print_array(a, 10); return 0; }