C语言标准库函数qsort(快速排序函数)

2023-10-28

 


 
 

一、函数原型

  qsort包含在<stdlib.h>头文件中,根据你给出的比较函数进行快速排序,通过指针移动实现排序,排序之后的结果仍然放在原数组中,使用qsort函数必须自己写一个比较函数。

函数原型:

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

参数:

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

返回值: 无返回值。
 
 

二、函数解析

常见的qsort写法:void qsort(s, n, sizeof(s[0]), cmp);

  • 第一个参数是参与排序的数组名(也就是开始排序的地址,所以&s[i],也是可以的)。
  • 第二个参数是参与排序的元素的个数。
  • 第三个参数是单个元素的大小(sizeof(s[0])这样就是获取到s[0]的元素大小)。
  • 第四个参数是一个函数,定义qsort排序排序规则的函数。

比较函数

cmp比较函数(qsort它的比较函数名取什么都可以,cmp只是我看大家都这么写,习惯了!)

比较函数cmp的定义: int cmp(const void *a, const void *b);

  • 返回值必须是int,两个参数的类型也必须是const void *。(变量名随意)
  • 如果a与b的位置需要互换,则需要返回正值;若不需要互换,则返回非正值即可。(也就是正值是互换,非正值维持原状)
  • 若是对int排序,升序,如果a比b大返回一个正值,小则返回负值,相等返回0。(*(int*)a - *(int*)b返回值)
  • 函数体内要对a,b进行强制类型转化后才能得到正确的值。((int*)
     
     

三、手写快排

void quick_sort(int q[], int l, int r)
{
    if (l >= r) return;

    int i = l - 1, j = r + 1, x = q[l + r >> 1];
    while (i < j)
    {
        do i ++ ; while (q[i] < x);
        do j -- ; while (q[j] > x);
        if (i < j) swap(q[i], q[j]);
    }
    quick_sort(q, l, j), quick_sort(q, j + 1, r);
}

 
 

四、使用qsort

1、对int数组排序

#include<stdio.h>
#include<stdlib.h>

int cmp(const void *a, const void *b){
	return *(int *)a - *(int *)b;//升序
//	return *(int *)b - *(int *)a;//降序
}

int main()
{
	int n,s[10000];
	scanf("%d", &n);
	for(int i=0;i<n;i++)
		scanf("%d",&s[i]);
	qsort(s, n, sizeof(s[0]), cmp);
	for(int i=0;i<n;i++)
		printf("%d ",s[i]);
	return 0;
 } 

 
 

2、对double数组排序

  在对浮点或者double型的对其进行判断返回相应的数(可以使用三目运算符或者if语句),因为要是使用像整型那样相减的话,如果是两个很接近的数则可能返回一个很小的小数(大于-1,小于1),而cmp的返回值是int型,因此会将这个小数返回0,系统认为是相等,失去了本来存在的大小关系。

#include<stdio.h>
#include<stdlib.h>

int cmp(const void *a, const void *b){
	return ((*(double *)a - *(double *)b)>0?1:-1);//升序
//	return ((*(double *)a - *(double *)b)<0?1:-1);//降序
}

int main()
{
	int n;
	double s[10000];
	scanf("%d", &n);
	for(int i=0;i<n;i++)
		scanf("%lf",&s[i]);
	qsort(s, n, sizeof(s[0]), cmp);
	for(int i=0;i<n;i++)
		printf("%lf ",s[i]);
	return 0;
 } 

 
 

3、对char数组排序

与int类型相似

#include<stdio.h>
#include<stdlib.h>

int cmp(const void *a, const void *b){
	return *(char *)a - *(char *)b;//升序
//	return *(char *)b - *(char *)a;//降序
}

int main()
{
	int n;
	char s[10000];
	scanf("%d", &n);
	getchar();
	for(int i=0;i<n;i++)
		scanf("%c",&s[i]);
	qsort(s, n, sizeof(s[0]), cmp);
	for(int i=0;i<n;i++)
		printf("%c ",s[i]);
	return 0;
 } 

 
 

4、对字符串排序

(1)char s[][]

strcmp() :字符串比较库函数,可以看看这篇博客博客

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

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

int main()
{
	int n;
	char s[1000][1000];
	scanf("%d", &n);
	for(int i=0;i<n;i++)
		scanf("%s",s[i]);
	qsort(s, n, sizeof(s[0]), cmp);
	for(int i=0;i<n;i++)
		printf("%d:%s\n",i,s[i]);
	return 0;
 } 

(2)char *s[]

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

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

int main()
{
	int n;
	char *s[1000];
	scanf("%d", &n);
	for(int i=0;i<n;i++){
		s[i] = (char *)malloc(sizeof(char *));//分配空间 
		scanf("%s",s[i]);
	}
	qsort(s, n, sizeof(s[0]), cmp);
	for(int i=0;i<n;i++)
		printf("%d:%s\n",i,s[i]);
	return 0;
 } 

5、对结构体排序

(1)一级排序

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct node{
	int id;
}s[100]; 

int cmp(const void *a, const void *b){
	struct node *aa = (node *)a;
	struct node *bb = (node *)b;
	return ((aa->id)>(bb->id))?1:-1;//升序
//	return ((aa->id)>(bb->id))?-1:1;//降序
}

int main()
{
	int n;
	scanf("%d", &n);
	for(int i=0;i<n;i++)
		scanf("%d",&s[i].id);
	qsort(s, n, sizeof(s[0]), cmp);
	for(int i=0;i<n;i++)
		printf("%d\n",s[i].id);
	return 0;
 } 

(2)二级排序

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct node{
	int id;
	char data;
}s[100]; 

int cmp(const void *a, const void *b){
	struct node *aa = (node *)a;
	struct node *bb = (node *)b;
	if(aa->id == bb->id)//若id相同,按照data排序 
		return aa->data - bb->data;
	else//否则按照id排序 
		return aa->id - bb->id;//升序
}

int main()
{
	int n;
	scanf("%d", &n);
	for(int i=0;i<n;i++)
		scanf("%d %c",&s[i].id,&s[i].data);
	qsort(s, n, sizeof(s[0]), cmp);
	printf("\n");
	for(int i=0;i<n;i++)
		printf("%d %c\n",s[i].id,s[i].data);
	return 0;
 } 
 
/*
5
1 c
1 b
1 a
2 a
3 a
*/ 

 
 

五、例题

题目链接

复杂排序规则题

#include<stdio.h>
#include<stdlib.h>
struct Data{
  long int id;
  int d;
  int c;
  int tote;
};
struct Data s[4][100000],r;
int cmp(const void *a,const void *b){
  struct Data e1=*(struct Data *)a;
  struct Data e2=*(struct Data *)b;
  if((e1.d+e1.c)!=(e2.d+e2.c)){
    return (e2.d+e2.c)>(e1.d+e1.c);
  }
  else if(e1.d!=e2.d){
    return e2.d>e1.d;
  }
  else{
    return e1.id>e2.id;
  }
}
int main()
{
  int a,b,N,L,H,g[4]={0};
  scanf("%d %d %d",&N,&L,&H);
  for(a=0;a<N;a++){
    scanf("%ld %d %d",&r.id,&r.d,&r.c);
    r.tote=r.d+r.c;
    if(r.d>=L&&r.c>=L){
      if(r.d>=H&&r.c>=H){
        b=0;
        s[b][g[0]++]=r;
      }
      else if(r.d>=H){
        b=1;
        s[b][g[1]++]=r;
      }
      else if(r.d>=r.c){
        b=2;
        s[b][g[2]++]=r;
      }
      else{
        b=3;
        s[b][g[3]++]=r;
      }
    }
  }
  qsort(s[0],g[0],sizeof(s[0][0]),cmp);
  qsort(s[1],g[1],sizeof(s[1][0]),cmp);
  qsort(s[2],g[2],sizeof(s[2][0]),cmp);
  qsort(s[3],g[3],sizeof(s[3][0]),cmp);
  printf("%d\n",g[0]+g[1]+g[2]+g[3]);
  for(a=0;a<4;a++)
    for(b=0;b<g[a];b++)
      printf("%ld %d %d\n",s[a][b].id,s[a][b].d,s[a][b].c);
  return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言标准库函数qsort(快速排序函数) 的相关文章

  • 前端布局 Flex(弹性)布局

    1 flex布局优点 操作方便 布局极为简单 移动端应用很广泛 pc端浏览器支持情况较差 IE11或者更低版本 不支持或仅部分支持 2 flex布局原理 flex意为 弹性布局 用来为盒状模型提供最大的灵活性 任何一个容器都可以指定为fle
  • Flutter实时动态UI刷新、数据交互

    setState 简介 setState 函数的作用是标记 StatefulWidget 中的 State 发生变化 需要重新构建 UI 即让Flutter架构自动实时刷新UI 当 StatefulWidget 的 State 发生变化时
  • 乔戈里推荐的新版Java学习路线,开源!

    Java 学习路线一条龙版 by 程序员鱼皮 所以我又抽空做了新版的 Java 学习路线一条龙 补充了很多内容 比如面试题 常用 Java 类库 常用软件等 让整个路线 字数翻倍 同时区分了各知识点的学习必要性 使得无论是急着找工作还是想花
  • vue3中setup语法糖下父子组件之间如何传递数据

    vue3中setup语法糖下父子组件之间如何传递数据 先弄明白什么是父子组件 父传子 子传父 组件间通信都有哪些方式 父子组件通信和兄弟组件通信的区别 先弄明白什么是父子组件 父子组件 分为父组件和子组件 Vue3中 父组件指的是包含一个或
  • 前端实现动态导航栏样式

随机推荐

  • 如何在电脑中安装虚拟机?

    第一步 先下载vmware软件 新手小白第一次下载软件会特别麻烦 自己也有可能在官网找不到相对应的软件 比如现在刚接触的我 内心无数的懵逼烦躁 还有很多很多的负面情绪 也懒得一个一个去摸索 下面是压缩包以及后续所需的激活码 加我百度网盘 别
  • 51单片机定时器/计数器T0

    选择方式0 方式1 方式2时 T0 T1的工作情况相同 选择方式3时 T0 T1的工作情况不同 方式0 13位定时器 计数器 TH0的高8位 TL0的低5位 方式1 16位定时器 计数器 TH0的高8位 TL0的低8位 方式2 自动重装的8
  • git出现error: invalid object for ‘xxxxx‘

    该问题说明git本地仓库 git objects里丢失了部分文件 执行git hash object w xxxxx 即可修复 xxxxx是invalid object for后面的文件路径
  • 向上管理(中高层核心能力的表现)

    向上管理 即在工作中为了让公司或上级以及自己取得更好的结果而下意识地配合上级一起工作的过程 在职业生涯中 向上管理其实也是工作能力的一部分 一项重要的职业技能 管理者不仅要做好向下管理 他们还要学会向上管理 1 向下管理 主要涉及的是管理者
  • 基于51单片机霍尔传感器测速(仿真+源程序)

    资料编号 196 下面是该资料仿真演示视频 196 基于51单片机霍尔传感器测速 仿真 源程序 全套资料 功能简介 51单片机计数测速转速测量 在仿真中等价于测量外部脉冲频率 如果修改输入脉冲的频率 在数码管上可实时显示当前频率 功能 霍尔
  • MTCNN人脸及特征点检测---代码应用详解(基于ncnn架构)

    本博记录为卤煮理解 如有疏漏 请指正 转载请注明出处 卤煮 非文艺小燕儿 本博地址 MTCNN人脸及特征点检测 代码应用详解 本文主要讲述当你拿到MTCNN的caffemodel后 如何使用它对一张图里的人脸进行检测和特征点标定 相当于一个
  • Qt信号和槽机制

    Qt信号和槽机制 什么是信号和槽 当某个事件发生 就执行一个操作 发生的事情就是信号 执行的操作就是槽 函数 给二者加上主体 信号发出者发出信号 信号接收者执行操作 将二者联系起来 松耦合 connect 函数 connect sender
  • 网络安全必备1000道面试题集锦(附答案)

    前言 以下为网络安全各个方向涉及的面试题 星数越多代表问题出现的几率越大 祝各位都能找到满意的工作 注 本套面试题 已整理成pdf文档 但内容还在持续更新中 因为无论如何都不可能覆盖所有的面试问题 更多的还是希望由点达面 查漏补缺 一 渗透
  • Error: @vitejs/plugin-vue requires vue (>=3.2.13) or @vue/compiler-sfc to be present in the dependen

    1 没有下载安装axios运行依赖 2 或者缺少这个库没有安装 npm i vue compiler sfc 3 node版本冲不冲突
  • Android Button、TextView等控件使用Toolbar中默认的返回图标

    Button backButton findViewById R id back button backButton setBackgroundResource R drawable abc ic ab back material R dr
  • 网站框架识别方法

    cms一般有dedecms 织梦 dzcms phpweb phpwind phpcms ecshop dvbbs siteweaver aspcms 帝国 zblog wordpress等 一般cms都有特定的文件 只需要识别特定的文件便
  • 运行jetty-maven-plugin时,出现错误

    ERROR Failed to execute goal org eclipse jetty jetty maven plugin 9 4 0 v20161208 run default cli on project kind perm w
  • 【漏洞复现】CVE-2023-22809 sudo提权漏洞

    一 前言 漏洞简介 Sudo中的sudoedit对处理用户提供的环境变量 如SUDO EDITOR VISUAL和EDITOR 中传递的额外参数存在缺陷 当用户指定的编辑器包含绕过sudoers策略的 参数时 拥有sudoedit访问权限的
  • 「iOS」swift 和 objectivec 获得对象的 class 或者 Type 的方法

    一 oc 中使用 oc 中非常简单 一行搞定 NSString str1 test str1 class 这里的 str1 class 就是获取对象 class 的方法 二 swift 中使用 时间紧 任务重 上代码 var str Str
  • Windows 找不到文件 ‘chrome‘。请确认文件名是否正确后,再试一次。

    Windows 找不到文件 chrome 请确认文件名是否正确后 再试一次 错误 当不运行 IDEA 项目 通过快捷键进入浏览器时 可能会出现以下错误 原因 未设置 chrome 路径 导致找不到路径报错 解决办法 1 在桌面上找到 chr
  • 解决qemu虚拟机中内存偏小的问题

    问题描述 最近测试部报了一个问题 云平台中设置大于4GB的内存并设置numa 启动linux2 6 32内核的客户机 之后操作系统中查看实际内存是1 9G 比设置内存小了大概2 1GB 使用版本信息如下 QEMU version 3 0 0
  • 替代MySQL半同步复制,Meta技术团队推出MySQL Raft共识引擎

    作者 Anirban Rahut Abhinav Sharma Yichen Shen Ahsanul Haque 原文链接 https engineering fb com 2023 05 16 data infrastructure m
  • 关于突破SQL注入限制的新思路

    http www bitscn com network protect 200804 139215 html 突然想我们是否可以用什么方法绕过SQL注入的限制呢 到网上考察了一下 提到的方法大多都是针对AND与 号和 号过滤的突破 虽然有点
  • Mac电脑使用小技巧

    Mac OS很多操作与Windows还是有较大的区别 需要一段时间适应 因此我整理了Mac OS的实用小技巧 希望帮助刚入手Mac的小伙伴轻松上手 一 使用预览直接修改图片大小 在遇到需要修改图片的大小 大家的惯有思维就是用Photosho
  • C语言标准库函数qsort(快速排序函数)

    文章目录 一 函数原型 二 函数解析 比较函数 三 手写快排 四 使用qsort 1 对int数组排序 2 对double数组排序 3 对char数组排序 4 对字符串排序 1 char s 2 char s 5 对结构体排序 1 一级排序