1 qsort原理介绍

函数原型:

void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*))

base – 指向要排序的数组的第一个元素的指针。
nitems – 由 base 指向的数组中元素的个数。
size – 数组中每个元素的大小,以字节为单位。
compar – 用来比较两个元素的函数。

注意cmp这个函数指针,返回值类型必须是int,参数是两个const void *,因此在写cmp函数时,可以选择在函数体内,再将a,b强转为所需要的类型;

我们以一个int数组为例,现在要将这个数组按照元素大小,升序排列。cmp函数与参数a,b对于qsort的影响是:

if a>b return positive
if a=b return 0
if a<b return negative

按照这个要求设计的return就会使得按照升序排序,注意是按照这个要求去设计所需要的返回值!只要能保住a,b在你设计的规则下,产生这样的返回值即可。而这三个条件刚好与a-b等价:

a>b return positive ~ a-b
a=b return 0        ~ a-b
a<b return negative ~ a-b

所以cmp函数可以写为:

int cmp(const void *a,const void *b){return *(int*)a-*(int*)b;/*按照升序排序*/  //降序就是 *(int*)b-*(int*)a;
}

strcmp函数,也就是把字符串str1和str2从首字符开始逐个字符的进行比较,直到某个字符不相同或者其中一个字符串比较完毕才停止比较。

int strcmp(char *str1,char * str2);

那么可以等价如下:

a>b return positive ~ a-b strcmp(a, b)//若字符串a大于字符串b,返回结果大于零;
a=b return 0        ~ a-b strcmp(a, b)//若字符串a等于字符串b,返回结果等于零;
a<b return negative ~ a-b strcmp(a, b)//若字符串a小于字符串b,返回结果小于零;

strcmp函数返回值正与我们所要求的升序设计一致,所以字符串操作cmp函数可写为:

int cmp(const void *a, const void *b) {return strcmp((char * )a, (char *)b);
}

2 qsort使用举例

2.1 一维数组排序

// 一维排序
int cmp1(const void *a, const void *b)
{int *x = (int *)a;int *y = (int *)b;return (*x) - (*y); // 升序,降序改为 (*y) - (*x)
}
// 一维排序
int arr[] = {9, 13, 12, -1, -1, 2, 8};
int arrLen = sizeof(arr) /sizeof(arr[0]);
qsort(arr, arrLen, sizeof(arr[0]), cmp1);
//排序结果arr1: -1 -1 2 8 9 12 13

2.2 二维数组排序

// 二维排序
int cmp2(const void *a, const void *b)
{int *x = (int *)a;int *y = (int *)b;return x[0] - y[0]; // 按照特性一升序,  按照特性二升序为 x[1] - y[1]
}
// 二维排序
int arr2[3][2] = {{7,6},{2,4},{1,2}}; // 三组数据:每组数据两个特性
qsort(arr2, 3, sizeof(arr2[0]), cmp2);
/*排序结果
arr2
1 2
2 4
7 6
*/

2.3 二维数组排序升级

// 二维排序
int cmp3(const void *a, const void *b)
{int *x = (int *)a;int *y = (int *)b;if (x[0] == y[0]) { // 特性一相同,按照特性二进行升序return x[1] - y[1];}return x[0] - y[0]; // 按照特性一升序
}
// 二维排序
int arr3[3][2] = {{1,6},{2,4},{1,2}}; // 三组数据:每组数据两个特性
qsort(arr3, 3, sizeof(arr3[0]), cmp3);
/*排序结果
arr3
1 2
1 6
2 4
*/

2.4 二维数组指针排序

//二维数组指针排序(注意)
int cmp4(const void **a, const void **b)
{int *x = (int *)(*a); // 注意区别!!int *y = (int *)(*b);if (y[1] == x[1]) { // 特性二相同,按照特性1进行降序return y[0] - x[0];}return y[1] - x[1]; // 按照特性二降序
}
//二维数组指针排序
int **arr4 = (int **)malloc(sizeof(int *)* 3); // 三组数据:每组数据两个特性
for (i = 0; i < 3; i++) {arr4[i] = (int *)malloc(sizeof(int) * 2);for (j = 0; j < 2; j++) {arr4[i][j] = i + j;}
}
qsort(arr4, 3, sizeof(arr4[0]), cmp4);
/*排序结果
arr4
2 3
1 2
0 1
*/

2.5 字符串排序

//字符串数组排序
int cmp5(const void *a, const void *b)
{char *x = *(char **)a;char *y = *(char **)b;return strcmp(x, y);
}
char *strs[3] = {"shn", "abc", "axy"};
qsort(strs, 3, sizeof(char *), cmp5);
/*排序结果
strs:
abc axy shn
*/

2.6 结构体中使用qsort排序

typedef struct arrInfo{int data;int index;
} ArrInfo;//结构体变量排序
int cmp6(const void *a, const void *b)
{ArrInfo *x = (ArrInfo *)a;ArrInfo *y = (ArrInfo *)b;if (y->data == x->data) { // 特性一data相同,按照特性二index进行降序return y->index - x->index;}return y->data - x->data; // 按照特性一data降序
}
//结构体中字段排序
ArrInfo *arr6 = (ArrInfo *)malloc(sizeof(ArrInfo)* 3); // 三组数据:每组数据两个特性
for (i = 0; i < 3; i++) {arr6[i].data = i;arr6[i].index = i + 1;
}
qsort(arr6, 3, sizeof(ArrInfo), cmp6);
/*排序结果
arr6
2 3
1 2
0 1
*/

2.7 结构体多级排序

根据学生信息,按照身高降序,身高相同时按照体重降序,体重也相同时按照姓名进行升序;

typedef struct StuInfo{char name[20];int high;int weight;
} StudentInfo;//学生信息排序
int cmp7(const void *a, const void *b)
{StudentInfo *x = (StudentInfo *)a;StudentInfo *y = (StudentInfo *)b;if (y->high== x->hight) { // 身高相同,按照体重进行降序if (y->weight == x->weight) { // 体重相同,按照姓名首字母进行升序return strcmp(x->name, y->name);}return y->weight - x->weight;}return y->high- x->high; // 按照身高降序
}
//学生信息排序
StudentInfo arr7[5] = {{"shn", 170, 65},{"xz",175, 80},{"axz",170, 65},{"dxz",175, 90},{"we",170, 60},}; // 5个学生
qsort(arr7, 5, sizeof(StudentInfo), cmp7);
/*排序结果
arr7
dxz 175 90
xz 175 80
axz 170 65
shn 170 65
we 170 60
*/

为了加强对qsort使用理解,可以练习力扣937题。

【总结分享和大家共同进步】

若存在错误之处,欢迎批评指正,若有收获,欢迎关注点赞~

C语言qsort排序相关推荐

  1. 【排序】什么都能排的C语言qsort排序详解【超详细的宝藏级别教程】深度理解qsort排序

    [排序]什么都能排的C语言qsort排序详解[超详细的宝藏级别教程]深度理解qsort排序 作者: @小小Programmer 这是我的主页:@小小Programmer 在食用这篇博客之前,博主在这里 ...

  2. C语言 qsort的用法 模拟EXCEL排序

    C语言 qsort的用法 模拟EXCEL排序 题目 Excel可以对一组记录按任意指定列排序.现请编写程序实现类似的功能. 输入 输入的第一行包含两个正整数N(<= 10^5)和C,其中N是记录 ...

  3. Bailian3719 学生信息用qsort排序【排序+字符串库函数】

    3719:学生信息用qsort排序 总时间限制: 1000ms 内存限制: 65536kB 描述 将输入的学生信息按名字排序后输出. 输入 每个学生信息是两行,第一行是名字,由英文字母和空格构成,最长 ...

  4. C语言qsort函数的实现

    C语言qsort函数的实现 1.首先阅读文档,查询qsort()函数的使用方法 2.开始实现自己创建的qsort()函数 1.首先阅读文档,查询qsort()函数的使用方法 void qsort (v ...

  5. c语言qsort函数(快速排序)

    c语言qsort函数(快速排序) 在学习c语言时我们常常会遇到一些排序的问题,在遇到这些排序的问题的时候,我们当然可以自己选择写出自己的排序方法来进行排序.但是我们今天要介绍的是c语言库函数中所提供的 ...

  6. C语言qsort快速排序函数详解

    直接进入主题,在c语言中qsort函数是用来快速排序的,qsort有4个参数,分别是数组地址,数组元素个数,数组元素字节大小和一个比较数组元素的函数指针.让我来看一下官方给出的使用标准,上图: 让我们 ...

  7. C语言qsort()函数

    C语言qsort()函数 #include<stdio.h> #include<stdlib.h> int cmp (const void * a, const void * ...

  8. R语言数据排序函数sort, order rank实战

    R语言数据排序函数sort, order & rank实战 目录 R语言数据排序函数sort, order & rank实战 #sort vs. order vs. rank函数基础 ...

  9. C语言常用排序方法大全

    C语言常用排序方法大全 /* ============================================================================= 相关知识介绍( ...

最新文章

  1. 模拟spring IOC、源码分析
  2. android webview参数,Android webView解析URL参数
  3. 中input怎么接受后台传值_[vue3]如何在vue3中优雅地使用vmodel?
  4. 在Chrome78浏览器上如何实现自动播放音视频
  5. linux内核模块的程序结构
  6. bzoj3390[Usaco2004 Dec]Bad Cowtractors牛的报复*
  7. 在Mysql中遇到关于区间范围内的索引优化
  8. Python 随机生成 范围内(周围) 经纬度 坐标信息
  9. frm考试可以用计算机,GARP协会:2021年FRM考试只能带这种计算器!
  10. 计算机任务栏隐藏恢复,电脑任务栏不见了怎么办?如何找回?
  11. vue图片压缩不失真_压缩图片大小(像素)
  12. 2017年全国大学生电子竞赛电源A题
  13. 分子量(Molar Mass, ACM/ICPC Seoul 2007, UVa1586)
  14. Redis大Key优化
  15. Python入门之基本语法
  16. 疯癫的我到了巅峰 -- 我的成人礼
  17. 机器学习中常用的几何距离测量和统计距离测量方法总结
  18. Java代码分层规范
  19. php卡片式,卡片式设计的优点和不适用性
  20. 机器学习实战(3)——分类

热门文章

  1. 无线局域网怎么设置?
  2. 西安80转2000坐标参数_【技术】西安80坐标、北京54坐标转国家2000坐标(附软件)...
  3. mac安装opencv(C++)
  4. python安装setuptools
  5. Java实现五子棋对战小游戏【完整版】
  6. 【计算机网络】IOS参考模型、TCP/IP体系结构与二三层网络架构
  7. 用计算机处理图像属于啥技术,计算机图像处理技术
  8. STM32小车——PWM电机调速
  9. 在css样式中隐藏元素,用JS改变的元素CSS样式,css里display :none 隐藏 block 显示
  10. 【Windows】使用U盘为Windows 11创建密码重置盘