分享一份归并排序代码,欢迎测试改进
程序代码:
/** *\file merge_sort.h *\brief 归并排序 *\date 2017/04/12 */ #ifndef __MERGE_SORT_H_2017_04_12__ #define __MERGE_SORT_H_2017_04_12__ #ifdef __cplusplus extern "C"{ #endif /** *\brief 归并排序中 设置merge_array的初始值 *\param[in] len 待初始化的数据规模 *\param[in] disoder_ary 等待排序的数据 *\param[in] merge_ary 初始化的对象 *\retval 1 初始化成功 *\retval 0 初始化失败 */ typedef int (*merge_set_fun)(unsigned int len, void *disoder_ary, void **merge_ary); /** *\brief 归并排序中 两个元素对比函数 *\param[in] cmp1 对比元素1 *\param[in] cmp2 对比元素2 *\retval 1 cmp1 > cmp2 *\retval 0 cmp1 = cmp2 *\retval -1 cmp1 < cmp2 */ typedef int (*merge_cmp_fun)(void *cmp1, void *cmp2); /** *\brief 归并排序中 赋值操作 *\param[in] lopr 被赋值的 等号 左边的数 *\param[in] ropr 赋值的 等号 右边的数 *\retval 1 赋值成功 *\retval 0 赋值失败 */ typedef int (*merge_agn_fun)(void **lopr, void *ropr); /** *\brief 归并排序中 获取排序结果 *\param[in] len 获取结果的数据规模 *\param[in,out] res_ary 等待排序的数据 *\param[in] merge_ary 归并排序后的结果 *\retval 1 获取结果成功 *\retval 0 获取结果失败 */ typedef int (*merge_res_fun)(unsigned int len, void *res_ary, void **merge_ary); /** *\brief 初始化归并排序环境 *\param[in] len 待排序的规模 *\param[in] disorder_array 待排序的数组 *\param[in] f_set 设置merge_array初始值函数 *\param[in] f_cmp 排序过程中需要的比较函数 *\param[in] f_agn 赋值操作函数 *\retval 1 初始化成功 *\retval 0 初始化失败 */ int merge_init(unsigned int len, void *disorder_array, merge_set_fun f_set, merge_cmp_fun f_cmp, merge_agn_fun f_agn); /** *\brief 销毁 */ void merge_destory(void); /** *\brief 归并排序 *\param[in] len 获取排序结果结果规模 *\param[in,out] res_array 获取排序结果 *\param[in] f_res 获取结果的回调 */ void merge_sort(unsigned int len, void *res_array, merge_res_fun f_res); #ifdef __cplusplus } #endif #endif//__MERGE_SORT_H_2017_04_12__
程序代码:
/** *\file merge_sort.cc *\brief 归并排序 *\date 2017/04/10 */ #include "merge_sort.h" #include <stdio.h> #include <assert.h> #include <stdlib.h> #include <errno.h> #include <string.h> static void **s_merge_array = (void**)0; ///< 交换的变量 static void **s_merge_swap = (void**)0; ///< 临时交换区 static unsigned int merge_len = 0; ///< 待排序的规模 static merge_cmp_fun mcmp_fun = NULL; ///< 对比函数 static merge_agn_fun magn_fun = NULL; ///< 赋值函数 static merge_set_fun mset_fun = NULL; ///< 设置merge_array的初始值 /** *\brief 初始化归并排序环境 *\param[in] len 待排序的规模 *\param[in] disorder_array 待排序的数组 *\param[in] f_set 设置merge_array初始值函数 *\param[in] f_cmp 排序过程中需要的比较函数 *\param[in] f_agn 赋值操作函数 *\retval 1 初始化成功 *\retval 0 初始化失败 */ int merge_init(unsigned int len, void *disorder_array, merge_set_fun f_set, merge_cmp_fun f_cmp, merge_agn_fun f_agn) { assert(len > 1); assert((void**)0 != disorder_array); assert(NULL != f_set); assert(NULL != f_set); assert(NULL != f_set); s_merge_array = (void **) malloc (sizeof(void*) * len); s_merge_swap = (void **) malloc (sizeof(void*) * len); if ((void**)0 == s_merge_array || (void**)0 == s_merge_swap){ printf("malloc failed errno(%d)!\n", errno); if (s_merge_array){ free(s_merge_array); s_merge_array = (void**)0; } if (s_merge_swap){ free(s_merge_swap); s_merge_swap = (void**)0; } return 0; } merge_len = len; mset_fun = f_set; mcmp_fun = f_cmp; magn_fun = f_agn; return mset_fun(len, disorder_array, s_merge_array); } /** *\brief 执行 归并排序 *\param[in] beg 起始位置下标 *\param[in] end 结束位置下标 */ static void __msort(unsigned int beg, unsigned int end) { unsigned int mid = 0; unsigned int i = 0, j = 0, k = 0; int ret = 0; assert (end >= beg); if (end - beg >= 1){ mid = (end - beg) / 2; __msort(beg, beg + mid); __msort(beg + mid + 1, end); // 归并 [beg, beg + mid] 和 [beg + mid + 1, end] 两个有序单元 for (i = beg, j = beg + mid + 1, k = beg; i <= beg + mid && j <= end; ++k){ ret = mcmp_fun(s_merge_array[i], s_merge_array[j]); if (-1 == ret){ magn_fun(&s_merge_swap[k], s_merge_array[i]); ++i; }else{ magn_fun(&s_merge_swap[k], s_merge_array[j]); ++j; } } while (i <= beg + mid){ // 将剩余的全部拷贝 magn_fun(&s_merge_swap[k], s_merge_array[i]); ++k; ++i; } while(j <= end){ // 将剩余的全部拷贝 magn_fun(&s_merge_swap[k], s_merge_array[j]); ++k; ++j; } memcpy(&s_merge_array[beg], &s_merge_swap[beg], (end - beg + 1) * sizeof(void*)); }else{ // end == beg 表示只有一个, 不处理 } } /** *\brief 归并排序 *\param[in] len 获取排序结果结果规模 *\param[in,out] res_array 获取排序结果 *\param[in] f_res 获取结果的回调 */ void merge_sort(unsigned int len, void *res_array, merge_res_fun f_res) { __msort(0, merge_len - 1); if (len <= 0 || NULL == res_array || NULL == f_res){// 不期望返回结果 return; } len = len > merge_len ? merge_len : len; // 取小的 f_res(len, res_array, s_merge_array); } /** *\brief 销毁 */ void merge_destory(void) { if (s_merge_array){ free(s_merge_array); s_merge_array = (void**)0; } if (s_merge_swap){ free(s_merge_swap); s_merge_swap = (void**)0; } merge_len = 0; mset_fun = NULL; mcmp_fun = NULL; magn_fun = NULL; }
程序代码:
/** *\file main.cc *\brief 归并排序 *\date 2017/04/10 */ #include "merge_sort.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <assert.h> #include <errno.h> static int s_len = 0; ///< 待排序的数列长度 static int s_ary[10000]; ///< 存放数列 /** *\brief 根据输入 随机创建 */ static void creat_ary(void) { int i = 0; printf("输入随机生成数列的数量:"); scanf("%d", &s_len); assert(s_len > 1 && s_len < 10000); srand(time(0)); for (i = 0; i < s_len; ++i){ s_ary[i] = rand()%10000; } } /** *\brief 输出随机产生的数列 */ static void print_ary(void) { int i = 0; for (i = 0; i < s_len; ++i){ printf("%d ", s_ary[i]); } printf("\n"); } /** *\brief 归并排序中 设置merge_array的初始值 *\param[in] len 待初始化的数据规模 *\param[in] disoder_ary 等待排序的数据 *\param[in] merge_ary 初始化的对象 *\retval 1 初始化成功 *\retval 0 初始化失败 */ int set_fun(unsigned int len, void *disoder_ary, void **merge_ary) { unsigned int i = 0; int *ary1 = NULL, **ary2 = NULL; assert((void**)0 != disoder_ary); assert((void**)0 != merge_ary); ary1 = (int *)disoder_ary; ary2 = (int **)merge_ary; for (i = 0; i < len; ++i){ ary2[i] = &ary1[i]; } return 1; } /** *\brief 归并排序中 两个元素对比函数 *\param[in] cmp1 对比元素1 *\param[in] cmp2 对比元素2 *\retval 1 cmp1 > cmp2 *\retval 0 cmp1 = cmp2 *\retval -1 cmp1 < cmp2 */ int cmp_fun(void *cmp1, void *cmp2) { int *int_cmp1 = NULL; int *int_cmp2 = NULL; assert(NULL != cmp1); assert(NULL != cmp2); int_cmp1 = (int*)cmp1; int_cmp2 = (int*)cmp2; if (*int_cmp1 > *int_cmp2){ return 1; }else if (*int_cmp1 == *int_cmp2){ return 0; } return -1; } /** *\brief 归并排序中 赋值操作 *\param[in] lopr 被赋值的 等号 左边的数 *\param[in] ropr 赋值的 等号 右边的数 *\retval 1 赋值成功 *\retval 0 赋值失败 */ int agn_fun(void **lopr, void *ropr) { int **int_lopr = NULL; int *int_ropr = NULL; assert((void**)0 != lopr); assert(NULL != ropr); int_lopr = (int **)lopr; int_ropr = (int *)ropr; *int_lopr = int_ropr; return 1; } /** *\brief 归并排序中 获取排序结果 *\param[in] len 获取结果的数据规模 *\param[in,out] res_ary 等待排序的数据 *\param[in] merge_ary 归并排序后的结果 *\retval 1 获取结果成功 *\retval 0 获取结果失败 */ int get_res_fun(unsigned int len, void *res_ary, void **merge_ary) { int *buf = NULL, **ary = (int**)0, *res = NULL; unsigned int i = 0; assert(0 <= len); assert(NULL != res_ary); assert((void**)0 != merge_ary); buf = (int*) malloc (len * sizeof(int)); if (NULL == buf){ printf("malloc failed, errno(%d)\n", errno); return 0; } ary = (int **)merge_ary; res = (int *)res_ary; for (i = 0; i < len; ++i){ buf[i] = *ary[i]; // 取指针指向的内容 } memcpy(res, buf, len * sizeof(int)); return 1; } int main(int argc, char **argv) { creat_ary(); print_ary(); merge_init(s_len, (void *)s_ary, set_fun, cmp_fun, agn_fun); merge_sort(s_len, (void *)s_ary, get_res_fun); merge_destory(); print_ary(); return 0; }
[此贴子已经被作者于2017-4-21 01:11编辑过]