c语言接口设计模式之抽象算法,以冒泡排序为例
任意数据类型数组排序(冒泡法)的c接口定义如下:
int bubble_sort(void *array, size_t nmemb, size_t sz, int (*cmp)(const void *, const void *, int), int sort_order)
(1)传入数组空指针array、数组每个元素的长度nmemb、数组元素个数sz,兼容不同的数据类型;
(2)不同数据类型的比较函数cmp,以回调函数的形式传入,实现排序算法与具体的数据类型解耦;
(3)sort_order指定是升序或者降序。当然,该参数也可以不要,但是bubble_sort接口的调用者则需要针对不同的数据类型,写升序和降序的比较函数,个人觉得更麻烦。
c代码参考魏老师的《C语言最佳实践》,有所改动。完整代码如下:
#include <stdint.h>
#include <string.h>
#include <malloc.h>
#define SWAP_MAX_NMEMB 100
#define ASC 0
#define DESC 1//交换两个变量
int swap(void *a, void *b, size_t nmemb)
{uint8_t tmp[SWAP_MAX_NMEMB];int sta;if (nmemb <= (size_t)SWAP_MAX_NMEMB){memcpy(tmp, a, nmemb);memcpy(a, b, nmemb);memcpy(b, tmp, nmemb);sta = 0;}else{sta = 1;}return sta;
}//数组冒泡排序
int bubble_sort(void *array, size_t nmemb, size_t sz, int (*cmp)(const void *, const void *), int sort_order)
{uint8_t *list = array;int sign, sta = 0;if (sort_order == ASC){sign = 1;}else{sign = -1;}for (size_t i = 0; i < sz - 1; i++){for (size_t j = 0; j < sz - 1 - i; j++){uint8_t *one = list + nmemb * j;uint8_t *next = list + nmemb * (j + 1);if (sign * cmp(one, next) > 0){sta = swap(one, next, nmemb);if (sta == 1) goto EXIT;}}}EXIT:return sta;
}//整形数值比较函数
static int int_cmp(const void *a, const void *b)
{const int *A = (const int *)a;const int *B = (const int *)b;return (*A - *B);
}//字符串比较函数
static int string_cmp(const void *a, const void *b)
{const char **A = (const char **)a;const char **B = (const char **)b;return strcmp(*A, *B);
}int main(void)
{int sta1, sta2;int arr_int[5] = { 3, 5, 1, 2, 4 };char *arr_string[5] = { "c1", "a1", "d1", "b1", "e1" };sta1 = bubble_sort(arr_int, sizeof(int), 5, int_cmp, ASC);sta2 = bubble_sort(arr_string, sizeof(char *), 5, string_cmp, DESC);return 0;
}