qsort()函数(quick sort)是快速排序算法,可以排序任意数据类型的数组其中就包括整形,浮点型,字符串甚至自定义的结构体类型。
下图是4个参数的含义
qsort(void *__base, size_t __nel, size_t __width,int (* _Nonnull __compar)(const void *, const void *));
1. void*base (首元素地址)
我们要排序一个数组,首先要知道从哪儿开始排序,所以先把首元素地址传给qsort函数。
2.size_t nell (元素个数)
我们还要知道数组从哪里结束,但是由于排序的不确定性我们不清楚最后的元素地址,所以将元素个数传入qsort函数。
3.size_t width (元素字节大小)
我们知道qsort函数可以排序任意类型的一组数据,因此我们采用void*类型的指针接收元素,但是void*类型的指针不能进行加减操作,也就无法移动。
那么在函数内部又是怎样操作变量的呢?
我们可以将void*类型的指针强制类型转换char*类型的指针后来操作元素。因为char*类型的指针移动一次的单位是一个字节,因此得知要操作的元素字节大小时,就可以让char*类型的指针移动该个字节到下一个元素,指针就可以指向那个元素了。
4.int (* _Nonnull __compar)(const void *, const void *))(比较函数)
我们要怎么给一组数据排序呢?例如可以给整形数据从小到大,也可以给浮点型数据从大到小,或者还可以比较字符串的大小也可以比较字符串的长度。这些我们就必须要写一个比较函数了。
具体的使用
要使用qsort函数我们要引用一个头文件<stdlib.h>
#include <stdlib.h>
比如我们要排序一个整形元素的数组
#include <stdio.h>
#include <stdlib.h>
int compar(const void *e1, const void *e2){
return (*(int *)e1 - *(int *)e2);
}
int main()
{
int arr[5] = {5, 2, 1, 4, 3};
qsort(arr, 5, sizeof(arr[0]), compar);
for (int i = 0; i < 5; i++){
printf("%d ", arr[i]);
}
return 0;
}
打印出来的结果:
可以看到升序排列,而改变成降序排列只需要改变compar里的内容即可。
#include <stdio.h>
#include <stdlib.h>
int compar(const void *e1, const void *e2){
return -((*(int *)e1 - *(int *)e2));
}
int main()
{
int arr[5] = {5, 2, 1, 4, 3};
qsort(arr, 5, sizeof(arr[0]), compar);
for (int i = 0; i < 5; i++) {
printf("%d ", arr[i]);
}
return 0;
}
可见,将return的值加上负号就能改变排列顺序,那么究竟是什么原因呢?接下来,我为大家用冒泡排序的方法实现这个函数。
#include <stdio.h>
#include <stdlib.h>
//交换函数的实现
void Swap(char *buf1, char *buf2, int width){
while (width)
{
char box = *buf1;
*buf1 = *buf2;
*buf2 = box;
buf1++;
buf2++;
width--;
}
}
//比较函数的实现
int cmp(const void *e1, const void *e2){
return *(int *)e1 - *(int *)e2;
}
void bubble_sort(void *base, int sz, int width, int (*cmp)(const void *, const void *)){
int i, j = 0;
for (i = 1; i < sz; i++){
for (j = 0; j < sz - i; j++){
// 调用cmp函数,这里可以规定函数排序的方式(升序or降序)
if (cmp((char *)base + j * width, (char *)base + (j + 1) * width) > 0){
// 满足上述条件,开始排序
Swap((char *)base + j * width, (char *)base + (j + 1) * width, width);
}
}
}
}
int main()
{
int arr[5] = {4, 3, 1, 2, 5};
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz, sizeof(arr[0]), cmp);
for(int i=0; i<5; i++){
printf("%d ",arr[i]);
}
return 0;
}
所以根据上述函数的内部实现可以得出return的数值如果大于0,那么就进行交换并且实现排序。那么如果想要反方向排序的话,只需要让return的数值取负值,及前一个数比后一个数小就交换,及降序排序。文章来源:https://www.toymoban.com/news/detail-744223.html
各种类型的cmp函数实现(除了整型,上面已包含)
1.浮点型
int cmp(const void *e1, const void *e2){
return (int)(*(float*)e1 - *(float*)e2);
}
2.比较字符串大小
int cmp(const void *e1, const void *e2){
return strcmp((char*)e1,(char*)e2);
}
3.比较字符的长度
int cmp(const void *e1, const void *e2){
return strlen((char*)e1) - strlen((char*)e2);
}
4.比较结构体变量文章来源地址https://www.toymoban.com/news/detail-744223.html
int cmp(const void *e1, const void *e2){
return (int)(((stu*)e1)->weight - ((stu*)e2)->weight);
}
到了这里,关于C语言sort()函数的使用 详细介绍的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!