qsort函数的使用
首先来为大家介绍一下 qsort 函数 注意:以下代码基于VS2022 X86环境下所编写,测试。如有问题,望指正!!
可以看到qsort函数被包含于<stdlib.h>的头文件中,并且有4个形参。
-
第一个是一个指向要排序的数组第一个元素的指针。它是一个无类型指针即空指针,意味着它可以指向任何类型的数据。
-
第二个是用来接收数组的元素的,size_t是一个无符号整数类型,用于表示对象的大小(以字节为单位)或数组中的元素数量。
-
第三个是用来计算数组中一个元素的大小有多大的,(以字节为单位)对于qsort函数来说是必要的,因为需要知道如何遍历数组中的每个元素。
-
第四个是函数指针,该函数用作比较两个元素的函数。这个函数应该接受两个const void*类型的参数(指向要比较的两个元素的指针),并返回一个整数来表示这两个元素的大小关系。(简单来说就是需要你自己写一个函数,来告诉qsort函数,应该以什么样的方式来排序,因为qsort函数不知道你需要排哪一种类型的数据,( qsort 函数可以排整数,小数,字符串,结构体等等),所以你需要告诉他你需要排什么类型,怎么排).
接下来让我们通过代码详细了解一下 qsort 函数(以整形排序举例)
//引用头文件
#include<stdio.h>
#include<stdlib.h>
int cmp (const void*e1,const void *e2)
{
return *(int*)e1-*(int*)e2;
/*关于cmp函数的返回值:如果e1指向大于e2的元素,那么返回大于0的数字。
如果e1指向等于e2的元素,那么返回0。
如果e1指向小于e2的元素,那么返回小于0的数字。*/
}
void Print(int* arr,int sz)
{
for(int i=0;i<sz;i++)
{
printf("%d",arr[i];
}
}
void test()
{
int arr[10]={5,8,9,6,4,3,2,0,1,7};//创建数组
int sz=sizeof(arr)/sizeof(arr[0]);//计算出数组长度
//调用qsort函数
qsort(arr,sz,sizeof(arr[0]),cmp);//传参
Print(arr,sz);
}
int main()
{
//创建一个测试函数
test();
return 0;
}
当然用来排结构体中的变量也是可以的,方法同上,我就不写注释了
#include<stdio.h>
#include<stdlib.h>
struct st
{
char name[20];
int age;
};
int cmp_st(const void* e1, const void* e2)
{
return (*(struct st*)e1).age - (*(struct st*)e2).age;
}
void Print(struct st* arr,int sz)
{
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i].age);
}
}
void text()
{
struct st s[3] = { {"zhangsan",32},{"lisi",20},{"wangwu",31} };
int sz = sizeof(s) / sizeof(s[0]);
qsort(s, sz, sizeof(s[0]), cmp_st);
Print(s, sz);
}
int main()
{
text();
return 0;
}
同理字符串也一样
#include<stdio.h>
#include<stdlib.h>
#include<string.h>//为了使用strcmp函数
struct st
{
char name[20];
int age;
};
int cmp(const void* e1, const void* e2)
{
return strcmp((*(struct st*)e1).name,(*(struct st*)e2).name);//比较字符串函数
}
void Print(struct st* arr, int sz)
{
for (int i = 0; i < sz; i++)
{
printf("%s ", arr[i].name);
}
}
void test()
{
struct st s[3] = { {"zhangsan",18},{"lisi",20},{"wangwu",19}};
int sz = sizeof(s) / sizeof(s[0]);
qsort(s, sz, sizeof(s[0]), cmp);
Print(s,sz);
}
int main()
{
test();
return 0;
}
最最最最后,让我们用冒泡排序简单模拟实现一下qsort函数!!
//模拟实现qsort函数
#include<stdio.h>
#include<stdlib.h>
int cmp(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2;
}
void Swap(char* buf1, char* buf2,int widgh)//定义一个Swap交换函数
{
for (int i = 0; i < widgh; i++)//一个字节一个字节的交换
{
char temp = *buf1;
*buf1 = *buf2;
*buf2 = temp;
buf1++;//交换完后都自增
buf2++;
}
}
void Print(int* arr,int sz)//打印函数
{
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}
void bubble_sort(void* base, int sz, int widgh, int(*cmp)(const void* e1, const void* e2))//模拟函数
{
for (int i = 0; i < sz-1; i++)
{
int j = 0;
for (j = 0; j < sz - i - 1; j++)
{//想一想,想一想,为什么要用强转成char*类型呢?为什么?为什么呢!!??
if (cmp((char*)base + j * widgh, (char*)base + (j + 1) * widgh)>0)
{//因为char类型的长度为1,单位为字节,可以通过后面的j*widgh来计算出这个类型的长度有多长,因为base 是空指针类型,不能用来计算,如果转换成其他(int(4个字节) , double(8个字节)等)就会混乱。
Swap((char*)base + j * widgh, (char*)base + (j + 1) * widgh,widgh);
}
}
}
}
void test()
{
int arr[10] = { 3,8,9,7,6,5,0,4,2,1 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz, sizeof(arr[0]), cmp);
Print(arr, sz);
}
int main()
{
test();
}