1.函数介绍
头文件<stdlib.h>
//缺陷:这个函数只能排指定类型的数据,通用性较差
// void qsort(void* base, //待排序的第一个元素的地址
// size_t num, //待排序数组的元素个数
// size_t size, //待排序数组中一个元素的大小
// int (*cmp)(const void* e1,const void* e2)
// 函数指针指向一个函数,这个函数用来比较两个元素
// e1 和 e2存的是需要比较的两个元素的地址
//)
返回值是一个int类型的参数,分为三种情况,如果cmp返回值小于0,则p1指向的元素会排在p2前面,返回值大于0则相反,等于0时排序的顺序是不确定的,所以这个函数是一个不稳定的函数.
1.1 cmp参数
这个就是这个函数的灵魂所在了,它指向一个比较两个元素的函数,注意两个形参必须是const void*型,同时在调用compar 函数(cmp实质为函数指针,这里称它所指向的函数也为cmp)时,传入的实参也必须转换成const void*型。在cmp函数内部会将const void*型转换成实际类型,这里这个cmp函数需要我们自己编辑,下面我给一个通用的cmp函数.
int compare (const void * a, const void * b) { if ( *(Type*)a < *(Type*)b ) return -1; if ( *(Type*)a == *(Type*)b ) return 0; if ( *(Type*)a > *(Type*)b ) return 1; } //注:这里的Type需要转换成实际的类型,举例如下 //升序排序 int compare (const void * a, const void * b) { return ( *(int*)a - *(int*)b ); } //降序排列 int compare (const void * a, const void * b) { return ( *(int*)b - *(int*)a ); }
2.不同参数使用qsort排序举例(这里只实现cmp函数)
2.1 int数组排序
int cmp (const void * a, const void * b) { return ( *(int*)a - *(int*)b ); }
2.2 结构体排序
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include<stdlib.h> typedef struct { char name[20]; // 学生姓名 int age; // 年龄 int score; // 成绩 }st; int cmp(const void* a, const void* b) { st* pa = (st*)a; st* pb = (st*)b; int num1 = pa->age; int num2 = pb->age; //return (int)num1 - num2; // 从小到大, return (int)num2 - num1; // 从大到小 } int main(void) { st students[5] = { {"张三",12,66}, {"李四",100,32}, {"小郑",78,88}, {"王五",87,90}, {"赵六",87,77} }; qsort(students, 5, sizeof(st), cmp); // 注意区别 students 与 st for (int i = 0; i < 5; i++) { printf("%s%4d%4d\t", students[i].name, students[i].age, students[i].score); } system("pause"); return 0; }
2.3 字符串排序
int cmp(const void *a,const void *b) { return *(char*)a-*(char*)b; }
2.4 浮点数排序
int cmp(const void *a,const void *b) { return *(double*)a>*(double*)b?1:-1; } //这里是考虑浮点数会存在精度丢失的问题,所以我们选择先比较再返回