今天主要给大家带来的是对于qsort函数的详细讲解以及使用冒泡排序模拟实现qsort函数,我们这里包括qsort函数的参数的理解和使用针对数组结构体进行升序降序排序,模拟qsort函数的参数。
1.qsort函数
1.1qsort函数的参数
对于qsort函数,我相信大家大部分还是第一次见到这个函数,我们先进入网站cplusplus
返回旧版,查找qsort函数
我们看到qsort函数的头文件是stdlib.h,我们可以发现qsort函数具定义为
void qsort (void* base, size_t num, size_t size,
int (*compar)(const void*,const void*));
在这里base是指我们要传入的数组 ,num是指传入数组的元素个数,size是指数组一个元素的所占的字节数,int (*compar)(const void*,const void*)是一个函数指针,在这里需要我们建立一个函数
这个函数指针的参数是void*类型,因为qsort函数可以排序任意类型的数据,使用时强制转换就可以使用。
1.2利用qsort函数排序整形数据
#include<stdio.h> #include <stdlib.h> int comper(const void* e1, const void* e2) { return *(int*)e1 - *(int*)e2; } int main() { int arr[5] = { 0,2,1,4,3 }; int sz = sizeof(arr) / sizeof(arr[0]); qsort(arr, sz, sizeof(arr[0]), comper); int i; for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } }
我们运行后可以得到
为升序排序,我们想要改为降序排序只需要将我们的comper函数进行修改
int comper(const void* e1, const void* e2) { return *(int*)e2- *(int*)e1 ; }
运行后为降序排序。
1.3利用qsort函数排序结构体数据
#include<stdio.h> #include <stdlib.h> typedef struct student { int age; char num[20]; }stu; int comper(const void* e1, const void* e2) { return ((stu*)e1)->age - ((stu*)e2)->age; } int main() { stu arr[3] = { 20,"zhangsan",19,"libai",22,"aiqiyi" }; int sz = sizeof(arr) / sizeof(arr[0]); qsort(arr, sz, sizeof(arr[0]), comper); int i; for (i = 0; i < sz; i++) { printf("%d ", arr[i].age ); } return 0; }
在进行比较名字是我们需要用到strcmp函数具体代码如下
int comper(const void* e1, const void* e2) { return strcmp(((stu*)e1)->num , ((stu*)e2)->num); }
2.模拟实现qsort函数
我们前面讲过想对数据进行排序可以使用冒泡排序,但是冒泡排序却有一些局限性,我们在这里利用冒泡排序来模拟实现qsort函数。
2.1冒泡排序
对于冒泡排序我们主要的代码为
void bulubulu(int arr[],int sz) { int i, j,temp; for (i = 0; i < sz - 1; i++) { for (j = 0; j < sz - 1 - i; j++) { if (arr[j] > arr[j + 1]) { temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } }
在这里我们主要就是依靠冒泡排序进行实现。
2.2代码实现
#include<stdio.h> #include <stdlib.h> #include <string.h> int comper(const void* e1, const void* e2) { return *(int*)e1 - *(int*)e2; } void swap(char *p,char*q,size_t sz) { int i; char temp; for (i = 0; i < sz; i++) { temp = *p; *p = *q; *q = temp; p++; q++; } } void bulubulu(void *base,size_t sz,size_t size) { int i, j; for (i = 0; i < sz - 1; i++) { for (j = 0; j < sz - 1 - i; j++) { if (comper((char*)base + j * size, (char*)base + (j + 1) * size)>0) { swap((char*)base+j*size,(char*)base+(j+1)*size,sz); } } } } void my_qsort(void *base,size_t num,size_t size,int(*comper)(const void *e1,const void *e2)) { bulubulu(base, num, size); } int main() { int arr[5] = { 0,2,1,5,3 }; int sz = sizeof(arr) / sizeof(arr[0]); my_qsort(arr, sz, sizeof(arr[0]), comper); int i; for (i = 0; i < sz; i++) printf("%d ", arr[i]); }
在这里,我们想排序一个整型数组,我们先得到数组有几个元素,每个元素占用几个字节,在我怕们的my_qsort函数中采用void*base是因为我们不知道要排序的元素是什么类型,我们进入冒泡排序也就是bulubulu函数中,在这里最为关键的是if (comper((char*)base + j * size, (char*)base + (j + 1) * size)>0)和swap((char*)base+j*size,(char*)base+(j+1)*size,sz)这两句,由于我们不知道想要排序的是什么类型,base是void*类型,想要使用swap函数和comper函数需要我们传送地址,我们将base强制转换为char*类型,我们还有一个元素占用的字节数size,再根据是第几个元素得到它的地址,在swap中我们是一个字节一个字节的进行交换。在这里comper是我们用户自己写的,其余的只需要my_qsort就可以解决。
今天的内容就结束了,希望大家可以学到很多东西。