前言
排序方法有很多种, 选择排序,冒泡排序,归并排序,快速排序等。 看名字都知道快速排序 是目前公认的一种比较好的排序算法(我没听书速度比这快的了,特殊场合例外),比选择排序,冒泡排序都要快。这是因为他速度很快,所以系统也在库里实现这个算法,便于我们的使用。 这就是qsort。
一、qsort函数原型
qsort函数:
void qsort( void *base, //待排序数据的起始位置
size_t num, //数据的元素个数
size_t width, //数据元素所占的字节
int (*cmp)(const void *e1, const void *e2 )//比较函数;e1 e2待比较两个元素的地址
);
注意:void* 指针可以接受任意类型的地址,因为void* 的指针没有类型,所以不能进行解引用操作,不能 ++/–;
函数的原型:
二、使用步骤
1.给整形数组排序
代码如下(示例):
主函数中:
int main()
{
int arr[10] = {
1,5,4,2,3,7,9,6,8,0 };
int sz = sizeof(arr) / sizeof(arr[0]);//计算数组中元素的个数
qsort(arr, sz, sizeof(arr[0]), cmp);
int i = 0;
for(i = 0; i < 10; i++)
printf("%d ",arr[i]);
return 0;
}
比较函数:
int cmp(const void* e1, const void* e2)
{
return (*(int*)e1 - *(int*)e2);//确定了比较元素的类型,先强制转化成整形指针再解引用
}
符合e1大于e2返回大于0的数,e1等于e2返回0,e1小于e2返回小于0的数。
比较后的结果:
2.给结构体排序
代码如下(示例):
主函数中:
struct Stu
{
char name[20];
int age;
};
int main()
{
struct Stu arr[] = {
{
"zhangsan",20},{
"lisi",31},{
"wangwu",15} };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), cmp);
int i = 0;
for (i = 0; i < 3; i++)
{
printf("%s %d\n", arr[i].name, arr[i].age);
}
return 0;
}
- 根据年龄大小给结构体排序:
int cmp(const void* e1, const void* e2)
{
return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
结果如下:
- 根据名字给结构体排序
int cmp(const void* e1, const void* e2)
{
return strcmp(((struct Stu*)e1)->name,((struct Stu*)e2)->name);
}
strcmp函数比较两个字符串时前者大于后者返回大于0的数,前者等于后者返回等于0的数,前者小于后者返回小于0的数。和cmp函数的返回类型相同。
结果如下:
三、用冒泡排序模拟实现qsort函数
代码如下(示例):
void s_wap(char* buf1,char* buf2,int width)
{
int i = 0;
for (i = 0; i < width; i++)
{
char tmp = *buf1;
*buf1 = *buf2;
*buf2 = tmp;
buf1++;
buf2++;
}
}
void bubble_sort(void* base, size_t sz, size_t width, int (*cmp)(const void* e1, const void* e2))
{
size_t i = 0;
//趟数
for (i = 0; i < sz - 1; i++)
{
size_t j = 0;
//相邻两个元素的比较
for (j = 0; j < sz - 1 - i; j++)
{
//如果不满足顺序就交换
if (cmp((char*)base + j * width, (char*)base + (j + 1) * width)>0)//先强制类型转换,再进行+操作表示根据数据类型访问的字节数再比较
{
s_wap((char*)base + j * width, (char*)base + (j + 1) * width,width);
}
}
}
}
整个bubble_sort()函数就展示完了。
举个例子:
在主函数中:
int main()
{
int arr[10] = {
1,5,4,2,3,7,9,6,8,0 };
int sz = sizeof(arr) / sizeof(arr[0]);//计算数组中元素的个数
bubble_sort(arr, sz, sizeof(arr[0]), cmp);
int i = 0;
for (i = 0; i < 10; i++)
printf("%d ", arr[i]);
return 0;
}
根据比较数据的类型自定义cmp函数:
//这里比较的是整形数据:
int cmp(const void* e1, const void* e2)
{
return (*(int*)e1 - *(int*)e2);//确定了比较元素的类型,先强制转化成整形指针再解引用
}
加上自己写的bubble_sort()函数程序执行结果如下: