我简化了书上的实现,每个数组元素是void*类型,两个void*元素的大小比较通过调用者提供的回调函数typedef int (*compare_fun)(void* a, void* b);实现
泣血的总结:
1. 减号“-”的优先级
>
按位右移“>>”的优先级
int len=3;
printf("%d\n",len);
printf("%d\n",len>>1);
printf("%d\n",len>>1-1);
printf("%d\n",(len>>1)-1);
2. 数组越界操作,free()时运行时报错
如果数组在使用时候越界(例如,读写arr[k]内容,而k大于等于arr长度)。当使用完数组arr并释放它时,会(运行时)报错:
*** glibc detected *** : free(): invalid next size (fast)
3. 学会释放int** 或者 void**
int length=...;
...
void** arr_tmp=(void**)malloc(length*sizeof(void*)); //#include <stdlib.h>
...
free(arr_tmp);
arr_tmp=NULL;
sort.h
#ifndef SORT_H #define SORT_H typedef enum _Ret{ RET_OK, RET_INVALID_PARAM, RET_FAIL }Ret; typedef int (*compare_fun)(void* a, void* b); Ret merge_sort(void** arr, int length, compare_fun compare); #endif
sort.c
#include <stdlib.h> #include "sort.h" //int (*compare_fun)(void* a, void* b); Ret merge_sort(void** arr, int length, compare_fun compare){ if(length==1 || length==0) return RET_OK; //merge_sort -----divide merge_sort(arr, (int)(length>>1), compare); merge_sort(arr+(int)(length>>1), length-(int)(length>>1), compare); //merge -----conquer void** arr_tmp=(void**)malloc(length*sizeof(void*)); //#include <stdlib.h> int i=0,j=length>>1,k=0; while(i<=(int)(length>>1)-1 && j<=(length-1)){ if(compare((void*)arr[i],(void*)arr[j])<0){ arr_tmp[k++]=arr[i++]; }else{ arr_tmp[k++]=arr[j++]; } } while(i<=(int)(length>>1)-1){ arr_tmp[k++]=arr[i++]; } while(j<=length-1){ arr_tmp[k++]=arr[j++]; } for(i=0;i<length;i++){ arr[i]=arr_tmp[i]; } free(arr_tmp); arr_tmp=NULL; return RET_OK; }
调用者程序 test.c
#include <stdio.h> #include <stdlib.h> #include "sort.h" //C语言中void*的长度和int的长度相等吗?如果这里换成double类型呢? int compare(void* a, void* b){ return (int)a-(int)b; } void print(int* arr,int length){ int i; for(i=0;i<length;i++){ printf("%d\t",arr[i]); } printf("\n"); } int main(void){ int arr[]={5,3,4,2,6,3,1}; print(arr,7); merge_sort((void**)arr,7,compare); print(arr,7); return 0; }