我们知道包含stdlib.h头文件后,就可以使用qsort这个库函数,接下来让我们了解他。
目录
#qsort函数介绍及举例使用
#qsort函数模拟实现
#下期预告
#qsort函数介绍及举例使用
qsort第一个参数是要排序的数组的首地址,第二个参数是要排序的数据数量,有几个,第三个参数是要排序的那个参数占几个字节,最后一个参数是函数指针,是让用户进行使用的函数,可以让用户对任意类型数据进行排序,一会儿我们会说到。
快速排序,可以实现像冒泡排序等的排序,同时能够对结构体排序时,将其其他数据一同排序,这是他的一大优点,接下来看举例:
#include #include #include typedef struct Qsort{char name[8];int age;}Qsort;int cmp(void* p1, void* p2){return ((Qsort*)p1)->age - ((Qsort*)p2)->age;}int main(){Qsort People[3];memset(People, 0, sizeof(Qsort) * 3);for (int i = 0; i < 3; i++){scanf("%s %d", People[i].name, &People[i].age);getchar();}qsort(People,3,sizeof(Qsort), cmp);for (int i = 0; i < 3; i++){printf("%s %d\n", People[i].name, People[i].age);}return 0;}
运行截图如下:
实现了年龄的排序,同时将名字也进行了移动,非常好用,接下来再举几个例子:
Example 1:对整数排序
#include #include int cmp(const void* a, const void* b){return *(int*)a - *(int*)b;}int main(){int arr[10] = { 1,2,3,7,3,1,5,9,2,5 };qsort(arr, 10, sizeof(int), cmp);for (int i = 0; i < 10; i++){printf("%d ", arr[i]);}return 0;}
Example 2:对浮点数排序
#include #include int cmp(const void* a, const void* b){return *(float*)a - *(float*)b;}int main(){float farr[5] = { 3.14,5.20,13.14,6.6,11.1 };qsort(farr, 5, 4, cmp);for (int i = 0; i < 5; i++){printf("%.2f\n", farr[i]);}return 0;}
Example 3:对名字排序
#include #include #include typedef struct Qsort{char name[8];int age;}Qsort;int cmp(void* p1, void* p2){return strcmp(((Qsort*)p1)->name , ((Qsort*)p2)->name);}int main(){Qsort People[3];memset(People, 0, sizeof(Qsort) * 3);for (int i = 0; i < 3; i++){scanf("%s %d", People[i].name, &People[i].age);getchar();}qsort(People,3,sizeof(Qsort), cmp);for (int i = 0; i < 3; i++){printf("%s %d\n", People[i].name, People[i].age);}return 0;}
你学会如何使用qsort了吗?如果还有疑问,接下来在qsort的模拟实现中也许会解答你的疑问惑
#qsort函数模拟实现
这里的核心排序我们将使用冒泡排序替代,这里本应该使用快速排序作为核心,但这里不涉及数据结构,就不多做介绍,感兴趣可以自己使用快速排序
#include #include #include typedef struct stu{char name[20];int age;}stu;int cmp(void* p1, void* p2);void my_qsort(void* base, size_t num, size_t sz, int (*cmp)(const void*,const void*));void swap(char* a, char* b, int sz);int main(){//qsort(base,num,size,cmp)stu student[3] = { {"nene",23},{"haha",21},{"miao",22} };my_qsort(student, 3, sizeof(stu), cmp);for (int i = 0; i < 3; i++){printf("%s %d\n", student[i].name, student[i].age);}return 0;}//因为我们不知道要比较的数据是什么类型,所以干脆传viod*类型,这样用户使用时//想比较什么类型的数据自己强制转换就好,就是用cmp函数,将void*类型的参数强//制转换成int*等类型,解引用后返回差值,或者是大小,返回的值将作为是否进行//数据交换的依据。void my_qsort(void* base, size_t num, size_t sz, int (*cmp)(const void*, const void*)){assert(base);//断言,判断传上来的指针是否为NULLfor (int i = 0; i < num - 1; i++){for (int j = 0; j 0)swap((char*)base + sz * j,(char*)base + sz * (j + 1), sz); //在这里,根据cmp的返回值决定是否交换}}}int cmp(void* p1, void* p2){return strcmp(((stu*)p1)->name, ((stu*)p2)->name);}//这个函数我们的参数设置为char*,因为我们依然不知道用户想要排序什么//类型的数据,但是我们交换时不能用void*,void*可以接受任何类型的数据//但是他没有大小,不能解引用,所以传上来sz这个大小,然后每个字节进行交换void swap(char* a, char* b, int sz){assert(a && b);while (sz--){char temp = *a;*a = *b;*b = temp;a += 1;b += 1;}}
#下期预告
指针进阶知识:
1.字符指针
2.指针数组
3.数组指针
4.一维数组传参,一级指针传参,区别
二维数组传参,二级指针传参,区别