目录
1.分析快速排序qsort函数
void qsort (void* base, size_t num, size_t size, int (*compar)(const void*,const void*));
void *base 传首元素的地址
size_t num 传数组的长度
size_t size 传每个元素的字节大小
int (*compar)(const void*,const void *)是一个函数的地址
这个函数是自己写的判断函数,返回值是int
如果第一个元素大于第二个元素返回大于一的数
如果第一个元素等于第二个元素返回等于一的数
如果第一个元素小于第二个元素返回小于一的数
2.思路分析
既然分析出qsort函数每个参数的意思那就可以通过分析参数的用处来实现通用的冒泡排序
void *base 首元素的地址不用说,先将首元素的地址传过去定位这个数组
size_t num 数组的长度,需要这个参数是为了数组确定到哪结束
size_t size 每个元素的字节大小是为了确定找到下一个字符串要走多大的空间
int(*compar)(const void*,const void*)是将相邻的两个元素传入这个数组用用户的方法来判断相邻的两个元素谁大谁小。
知道以上信息,pop_sort就可以写起来了
首先冒泡排序的通用模式肯定先要将冒泡排序写出来
#include <stdio.h>
void pop_sort(void *base,int num,int sz,int (*cmp)(const void e1,const void e2))
{
int i=0;
int j=0;
for(i=0;i<num;i++)//确定趟数
{
for(j=0;j<num-i-1;j++)//确定每趟的次数
{
}
}
}
既然用户已经按照规则将判断元素那个大那个小的函数写出来了那就可以利用,用户函数的返回值来进行按一定规则进行排序(这里选择的是升序),由于用户没有将相邻两个元素传入他的方法,所以我们需要将相邻两个元素的地址传入这个方法
#include <stdio.h>
void pop_sort(void *base,int num,int sz,int (*cmp)(const void e1,const void e2))
{
int i=0;
int j=0;
for(i=0;i<num;i++)//确定趟数
{
for(j=0;j<num-i-1;j++)//确定每趟的次数
{
if(cmp((char*)base+j*sz,(char*)base+(j+1)*sz)>0)
{
//base是首元素的地址,sz是元素的大小,用j和j+1正好相邻,用j,j+1分别乘元素大小得到
//相邻两个数组的大小,传入用户写的函数中得到的返回值于0比较,由于是升序,所以返回是大
//于0的是开始交换
}
}
}
}
写一个交换函数,由于我们不知道传上来的数据类型是什么。所以采取一个字节一个字节的换
#include <stdio.h>
void swap(char *buf1,char*buf2,int sz)
{
int i=0;
for(i=0;i<sz;i++)
{
char tmp=*buf1;
*buf1=*buf2;
*buf2=tmp;
buf1++;
buf2++;
//每次要交换一个字节总共要交换sz个字节
}
}
void pop_sort(void *base,int num,int sz,int (*cmp)(const void e1,const void e2))
{
int i=0;
int j=0;
for(i=0;i<num;i++)//确定趟数
{
for(j=0;j<num-i-1;j++)//确定每趟的次数
{
if(cmp((char*)base+j*sz,(char*)base+(j+1)*sz)>0)
{
swap(char*)base+j*sz,(char*)base+(j+1)*sz),sz);
}
}
}
}
代码实现
#include <stdio.h>
void swap(char* buf1, char* buf2, int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
char tmp = *buf1;
*buf1 = *buf2;
*buf2 = tmp;
buf1++;
buf2++;
}
}
//写一个通用的冒泡排序
void pop_sort(void* base, int num, int sz, int (*cmp)(const void* e1, void* e2))
{
/
int i = 0;
int j = 0;
for (i = 0; i < num; i++)//循环的趟数
{
for (j = 0; j < num - i - 1; j++)//每趟循环的次数
{
if (cmp((char*)base +j* sz, (char*)base +(j+1) * sz) > 0)
{
swap((char*)base + j * sz, (char*)base + (j + 1) * sz, sz);
}
}
}
}
int cmp_int(void *e1,void *e2)
{
return *((int *)e1) - *((int*)e2);
}
int main()
{
int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };
int sz = sizeof(arr[0]);
int num = sizeof(arr) / sizeof(arr[0]);
pop_sort(arr, num, sz, cmp_int);
int i = 0;
for (i = 0; i < num; i++)
{
printf("%d", arr[i]);
}
}
注意:
void* 可以接收所有的指针,只需要用的时候强制转换成所以要的类型即可
void* 不可以加减也不可以访问
站在程序员的角度来写这个函数的时候,我们什么都不知道,所以要考虑所有情况