qsort函数简介
qsort函数包含在C 标准库 - <stdlib.h>中
qsort 的函数原型是:
void qsort(voidbase,size_t num,size_t width,int(__cdeclcompare)(const void*,const void*))
void*base为要排序的数组名(地址)
size_t num为元素个数
size_t width为每个元素所占空间大小,字节数
int(__cdecl*compare)(const void*,const void*)为库函数作者提供给使用者自己编写的一个比较函数返回值为int
如果compar返回值小于0(< 0),那么p1所指向元素会被排在p2所指向元素的左面;
如果compar返回值等于0(= 0),那么p1所指向元素与p2所指向元素的顺序不确定;
如果compar返回值大于0(> 0),那么p1所指向元素会被排在p2所指向元素的右面。
__cdecl 是C Declaration的缩写(declaration,声明),表示C语言默认的函数调用方法:所有参数从右到左依次入栈,这些参数由调用者清除,称为手动清栈。被调用函数不会要求调用者传递多少参数,调用者传递过多或者过少的参数,甚至完全不同的参数都不会产生编译阶段的错误。
例主函数代码
struct Stu
{
char name[20];
int age;
};
int main()
{
int arr[10]={1,4,2,5,3,6,9,7,8,10};
char arr1[10]="ABCEGDF";
struct Stu s[3] = { {"zhangsan", 30},{"lisi", 34},{"wangwu", 20} };
int sz=sizeof(s)/sizeof(s[0]);
qsort(arr1,sz,sizeof(s[0]),cmp_char);
// for(int i=0;i<sz;i++)
// {
// printf("%d ",arr[i]);
// }
printf("%s\n", arr1);
return 0;
}
compare函数
int类型比较
int cmp_int(const void*e1,const void*e2)
{
return *(int*)e1-*(int*)e2;
}
char类型比较
int cmp_char(const void*e1,const void*e2)
{
return *(char*)e1-*(char*)e2;
//return strcmp((char*)e1,(char*)e2);
}
double类型比较
注意:在对浮点或者double型的一定要用三目运算符,因为要是使用像整型那样相减的话,如果是两个很接近的数则可能返回一个很小的小数(大于-1,小于1),而cmp的返回值是int型,因此会将这个小数返回0,系统认为是相等,失去了本来存在的大小关系(转载)
int cmp_char(const void*e1,const void*e2)
{
return *(char*)e1 > *(char*)e2 ? 1 : -1;
}
按结构体年龄(int)
int sort_by_age(const void* e1, const void* e2)
{
return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
按结构体名字(字符串)
int sort_by_name(const void*e1, const void*e2)
{
return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}
自己模拟实现qsort函数
模拟实现冒泡qsort函数
void bubble_qsort(void* base,
int sz,
int width ,
int (*cmp)(const void*e1, const void*e2)
)
{
for (int i = 0; i < sz-1; ++i)//趟数
{
for (int j = 0; j < sz-i-1; ++j)
{
if(cmp((char*)base+j*width, (char*)base+(j+1)*width)>0)//判断函数返回值
{
swap((char*)base+j*width, (char*)base+(j+1)*width,width);
//转换类型为char* 方便与width结合使用 第j和第j+1个调换
}
}
}
}
交换函数
void swap(char*buffer1,char*bufffer2,int width)
{
for(int i=0;i<width;i++)//由于是char* width限制按字节交换
{
char tmp=*buffer1;
*buffer1=*bufffer2;
*bufffer2=tmp;
buffer1++;
bufffer2++;
}
}