利用C实现泛型(generics)效果---原地洗牌,快速排序
来源:互联网 发布:网店数据同步系统 编辑:程序博客网 时间:2024/06/05 18:29
用一个函数实现一个算法,能够应用在不同的数据类型(int,double,字符数组)上,这在C++,python等高级语言中是很常见的。
灵活地利用C中的void指针,内存操作,函数指针也可以实现类似的效果。
用void指针指向特定元素的地址,如果传入元素占内存大小(如sizeof(int),sizeof(double)),可以用memcpy实现赋值操作。
如果实现了用于元素间比较或四则运算的函数并将其指针传入(如int (*cmp)(void*,void*)),则能在算法中不考虑数据类型实现更多功能。
比如下面一段函数,实现了原地洗牌,快速排序两种算法:
#include <stdlib.h>#include <string.h>#include <time.h>//omit ptr check when malloc and realloc void swap(void* ap, void* bp, int elem_size) {void* buffer = malloc(elem_size);memcpy(buffer, ap, elem_size);memcpy(ap, bp, elem_size);memcpy(bp, buffer, elem_size);free(buffer);}void randomize_in_place(void* arr, int n, int elem_size) {int rand_place;srand((unsigned int)time(NULL));for(int i=0; i<n; i++) {rand_place = rand() % (n-i) + i;swap((char*)arr+i*elem_size, (char*)arr+rand_place*elem_size, elem_size);}}int int_cmp(const void* ap, const void* bp) {return *(int*)ap - *(int*)bp;}int double_cmp(const void* ap, const void* bp) {if(*(double*)ap - *(double*)bp < 0)return -1;else if(*(double*)ap - *(double*)bp == 0)return 0;elsereturn 1;}int charptr_cmp(const void* ap, const void* bp) {return strcmp(*(char**)ap, *(char**)bp);}int randomized_partition(void* arr, int p, int r, int elem_size, int (*compar)(const void*, const void*)) {srand((unsigned int)time(NULL));int rand_elem_index = rand() % (r-p+1) + p;char* rand_elem_ptr = (char*)arr + rand_elem_index * elem_size;char* pivot_ptr = (char*)arr + r * elem_size;swap(rand_elem_ptr, pivot_ptr, elem_size);// start to partition, arr[r]=pivot// p<=k<=i arr[k]<=pivot, i+1<=k<=j-1 arr[k]>pivot int i = p - 1;char* ith_elem_ptr = NULL;char* jth_elem_ptr = NULL;for(int j=p; j<r; j++) {jth_elem_ptr = (char*)arr + j * elem_size;if(compar(jth_elem_ptr, pivot_ptr) <= 0) {i = i + 1;ith_elem_ptr = (char*)arr + i * elem_size;swap(ith_elem_ptr, jth_elem_ptr, elem_size);}}swap((char*)arr+(i+1)*elem_size, pivot_ptr, elem_size);return i+1;}void recursive_qsort(void* arr, int p, int r, int elem_size, int (*compar)(const void*, const void*)) {if(p < r) {int q = randomized_partition(arr, p, r, elem_size, compar);recursive_qsort(arr, p, q-1, elem_size, compar);recursive_qsort(arr, q+1, r, elem_size, compar);}}void generic_qsort(void* arr, int n, int elem_size, int (*compar)(const void*, const void*)) {recursive_qsort(arr, 0, n-1, elem_size, compar);}
int main(int argc, char** argv) {int int_array[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};randomize_in_place(int_array, 10, sizeof(int)); //testgeneric_qsort(int_array, 10, sizeof(int), int_cmp); //testdouble double_array[6] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};randomize_in_place(double_array, 6, sizeof(double)); //testgeneric_qsort(double_array, 6, sizeof(double), double_cmp); //testchar* charptr_array[6] = {"generics", "hccc", "spring", "summer", "autumn", "winter"};randomize_in_place(charptr_array, 6, sizeof(char*)); //testgeneric_qsort(charptr_array, 6, sizeof(char*), charptr_cmp); //test}
在《C++编程思想》那本书中的,“一个袖珍的C库”那一小节,利用类似的思想实现了一个stash,不过那里使用的是字符拷贝,而且只考虑了元素存取,没有更复杂的操作。
- 利用C实现泛型(generics)效果---原地洗牌,快速排序
- 利用C实现泛型效果(generics)---vector
- C原地快速排序
- 利用手摇算法实现原地归并排序
- 利用手摇法实现原地归并排序
- 如何利用C语言中的qsort库函数实现快速排序?
- 如何利用C语言中的qsort库函数实现快速排序
- 排序算法(C实现)--------- 快速排序
- 快速排序c实现
- 快速排序C实现
- 快速排序C实现
- 快速排序C实现
- 快速排序(C实现
- Swift实现洗牌动画效果
- 快速排序算法实现(C++)
- 快速排序算法(C & Java 实现)
- 快速排序算法实现(C版)
- 快速排序(c语言实现)
- HDFS架构
- 最簡單的東西總是最容易被忽視——談看不見的設計
- mysql general log
- 在 Ubuntu 上搭建 VPN 服务器
- 常见排序算法
- 利用C实现泛型(generics)效果---原地洗牌,快速排序
- 熬之滴水成石:最想深入了解的内容--windows内核机制(12)
- HttpHandler与HttpModule使用
- 同一端口如何区分不同的Socket
- oracle 11g 安装之后如何为用户解锁、加锁
- GAE发生在OS X上socket.error: [Errno 48] Address already in use 问题的解决方法
- android camera
- 对扑克牌字符串数组进行排序
- 浙工ACM1033