qsort函数

目录

  • 1.什么是qsort函数
  • 2.实现一个qsort函数
  • 3.用qsort函数排序一个结构体
  • 4.模仿qsort的功能实现一个通用的冒泡排序

1.什么是qsort函数

我们以前学习过的一些排序算法,如冒泡、希尔、快排等等,它们速度有快有满,但是这些排序都只能排序一种类型的变量,如果想排序另一种变量就需要另写一个排序, 那么有没有什么排序是“万能的”呢,什么类型数据都能排的呢?

答案就是qsort函数

qsort函数实现了一种快速排序算法,对一个由n个元素组成的数组进行排序,每个元素的宽度为字节。参数base是一个指向要排序的数组基数的指针,qsort用排序后的元素覆盖这个数组。参数compare是一个指向用户提供的例程的指针,用于比较两个数组元素并返回一个指定它们之间关系的值。

这是qsort函数的官方定义:
在这里插入图片描述

这个函数有四个参数

  • 第一个参数base是待排数组的起始地址
  • 第二个参数num是数组的元素个数,也就是数组的大小
  • 第三个参数width是一个元素的大小,单位是字节,也就是一个元素所占大小
  • 第四个参数compare是一个函数指针,这个参数较为复杂,接下来我们展开讲

在排序中,比较整形或比较浮点型可以用大于,小于,等于;比较两个字符串可以用strcmp函数;但是如果比较两个结构体怎么比较,按照结构体中哪个元素进行比较呢?所以不同类型的元素应用不同的方法去比较

这也就是compare这个函数干的事,在这个函数里,我们自己写两个元素应该怎么比较
compare这个函数指针传回qsort函数,qsort就会按照compare函数中比较的方法,对数组中元素进行比较

compare函数中,elem1指的是要比较的两个元素中第一个元素的地址,elem2是另一个要比较的元素的地址,因为这个函数官方在定义的时候,并不知道要比较什么类型的元素,所以用void*类型.

compare函数是有返回值的:
在这里插入图片描述

  • elem1小于elem2,返回负数
  • elem1大于elem2,返回正数
  • elem1等于elem2,返回0

按照comparer函数的定义,数组以递增的顺序进行排序。要按递减顺序对数组进行排序,颠倒comparer函数中 "大于 "和 "小于 "的含义。


2.实现一个qsort函数

有一个存放int类型变量的数组arr

int arr[10] = { 10,9,8,7,6,5,4,3,2,1 };

然后使用qsort函数

  • 第一个参数是数组名arr
  • 第二个参数是数组长度int size = sizeof(arr) / sizeof(arr[0]);
  • 第三个参数是一个元素的大小sizeof(arr[0])
  • 第四个参数是函数指针cmp_int

cmp_int函数中,因为传的参数是void*类型,并且待排数组是int类型的,所以在比较函数中,需要将void*类型的变量强制转换成int*类型的指针再进行解引用

如果是排升序,就按照cmp_int函数中参数的顺序将两个指针解引用后相减,否则就颠倒两个指针的顺序

代码如下:

#include <stdio.h>int cmp_int(const void* e1, const void* e2)
{//排升序return *(int*)e1 - *(int*)e2;//排降序//return *(int*)e2 - *(int*)e1;
}int main()
{int arr[10] = { 10,9,8,7,6,5,4,3,2,1 };int size = sizeof(arr) / sizeof(arr[0]);qsort(arr, size, sizeof(arr[0]), cmp_int);for (int i = 0; i < size; i++){printf("%d ", arr[i]);}
}

3.用qsort函数排序一个结构体

下面我们用qsort排序一个结构体
结构体如下:

struct stu
{int age;char name[10];
};

然后使用qsort函数,结构体中有整形和字符串两个元素,这两个元素都可以进行比较和排序

首先我们按照年龄来排序,比较年龄的函数命名为cmp_by_age,将两个void*类型的形参强转成struct stu*类型,访问它们的age元素并相减

int cmp_by_age(const void* e1, const void* e2)
{return ((struct stu*)e1)->age - ((struct stu*)e2)->age;
}

首先我们按照姓名来排序,比较年龄的函数命名为cmp_by_name,将两个void*类型的形参强转成struct stu*类型,访问它们的name元素,可以用strcmp比较字符串间的大小

int cmp_by_name(const void* e1, const void* e2)
{return strcmp(((struct stu*)e1)->name, ((struct stu*)e2)->name);
}

完整代码:

#include <stdio.h>
#include <string.h>struct stu
{int age;char name[10];
};int cmp_by_age(const void* e1, const void* e2)
{return ((struct stu*)e1)->age - ((struct stu*)e2)->age;
}int cmp_by_name(const void* e1, const void* e2)
{return strcmp(((struct stu*)e1)->name, ((struct stu*)e2)->name);
}int main()
{struct stu arr[3] = { {18,"jack"},{30,"andy"},{25,"ride"} };int size = sizeof(arr) / sizeof(arr[0]);qsort(arr, size, sizeof(arr[0]), cmp_by_age); //按照年龄排序qsort(arr, size, sizeof(arr[0]), cmp_by_name); //按照姓名排序return 0;
}

4.模仿qsort的功能实现一个通用的冒泡排序

模仿qsort函数实现冒泡排序,改进后的冒泡排序的函数列表中应与qsort函数一样

void BubbleSort(void* base, size_t size,size_t width,int(*cmp)(const void* e1,const void*e2))

在以往的冒泡排序中,有两层循环,在两层循环中有一个比较两个数大小的if语句,在if语句中有一个交换语句
在改进型的冒泡中,也都是这些语句,只不过改进的是if语句中判断两个数大小和交换函数而已

在改进的冒泡排序中,比较两个元素的大小是调用额外定义出的cmp函数
但是怎么将两个待比较的元素传到cmp函数中是个问题,因为接收进来的数组是void*类型的,不知道元素具体是什么类型,无法用下标去访问所以只能将base强转成char*类型,通过指针的偏移量去访问每个元素,每两个元素中间隔着一个width字节的宽度,所以用(char*)base+j*width取出第一个元素的地址,用(char*)base+(j+1)*width取出第二个元素的地址

放到cmp函数中进行比较

cmp((char*)base + j * width, (char*)base + (j + 1) * width)

紧接着如果两个元素需要进行交换,就要使用交换函数,还是因为不知到元素是什么类型的,所以还是一个字节一个字节得交换

void swap(char* buf1, char* buf2, int width)
{for (int i = 0; i < width; i++){char tmp = *buf1;*buf1 = *buf2;*buf2 = tmp;buf1++;buf2++;}
}

此时,模仿qsort函数实现冒泡排序就完成了,下面是完整代码:

#include<stdio.h>
#include <string.h>struct stu
{int age;char name[10];
};int cmp_by_age(const void* e1, const void* e2)
{return ((struct stu*)e1)->age - ((struct stu*)e2)->age;
}int cmp_by_name(const void* e1, const void* e2)
{return strcmp(((struct stu*)e1)->name, ((struct stu*)e2)->name);
}int cmp_int(const void* e1, const void* e2)
{return *(int*)e1 - *(int*)e2;
}void swap(char* buf1, char* buf2, int width)
{for (int i = 0; i < width; i++){char tmp = *buf1;*buf1 = *buf2;*buf2 = tmp;buf1++;buf2++;}
}void BubbleSort(void* base, size_t size,size_t width,int(*cmp)(const void* e1,const void*e2))
{int i = 0;for (i = 0; i < size-1; i++){int j = 0;for (j = 0; j < size - i - 1; j++){if (cmp((char*)base + j * width, (char*)base + (j + 1) * width)>0){swap((char*)base + j * width, (char*)base + (j + 1) * width, width);}}}
}void test1()
{int arr[10] = { 10,9,8,7,6,5,4,3,2,1 };int size = sizeof(arr) / sizeof(arr[0]);BubbleSort(arr, size, sizeof(arr[0]), cmp_int);
}void test2()
{struct stu arr[3] = { {18,"jack"},{40,"andy"},{35,"mary"} };int size = sizeof(arr) / sizeof(arr[0]);BubbleSort(arr, size, sizeof(arr[0]), cmp_by_age);//按照年龄排序BubbleSort(arr, size, sizeof(arr[0]), cmp_by_name);//按照姓名排序
}int main()
{test1();test2();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/254092.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

qsort函数的使用方法

前言 qsort函数是C语言库函数内给我们提供的一个可以实现排序的函数 它不仅可以排序数组&#xff0c;还可以排序字符串&#xff0c;以及结构体类型 下面是qsort函数的使用方法以及注意事项 一、了解qsort函数 根据MSDN提供的参数 由此我们可以知道 使用qsort函数需要引用头文…

简单介绍一下qsort函数

目录 一.回调函数 二.qsort函数 三.void*指针 四.用qsort函数进行升序排序 1.整形数组排序 2.结构体数组排序 3.字符数组排序 五.使用冒泡排序模拟实现qsort函数 一.回调函数 回调函数就是一个通过函数指针调用的函数。如果你把函数的指针&#xff08;地址&#xff09;…

C语言qsort函数的使用详解

文章目录 一、qsort函数简介1.函数原型2.参数含义3.比较函数详解 二、比较函数使用案例1.整型数组2.字符数组3.double型数组4.字符串1.按字符串首字母进行排序2.按字符串长度进行排序3.按字典进行排序 5.结构体 三、qsort函数完整使用案例1.整型数组2.字符数组3.double型数组4.…

qsort函数用法 + 模拟实现qsort函数

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前是C语言学习者 ✈️专栏&#xff1a;【C/C】算法 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞…

C语言qsort函数用法

qsort函数简介 排序方法有很多种&#xff1a;选择排序&#xff0c;冒泡排序&#xff0c;归并排序&#xff0c;快速排序等。 看名字都知道快速排序是目前公认的一种比较好的排序算法。因为他速度很快&#xff0c;所以系统也在库里实现这个算法&#xff0c;便于我们的使用。 这就…

qsort函数讲解

qsort函数的作用是将所有数据排序&#xff0c;那么它和普通的冒泡排序或者选择排序有什么区别呢&#xff1f;它不仅仅可以排序数组中的数字&#xff0c;还可以排序结构体。当然升序和降序它都支持&#xff0c;不过输入参数的顺序会有所不同&#xff0c;下面我们来详细讲解一下这…

【C语言】qsort函数的使用和模拟实现

本篇文章我们来了解一下回C语言中qsort函数的使用方法和模拟实现。这是一个通用性很强而且非常方便的库函数&#xff0c;通过这篇文章希望能让你了解sort函数。 目录 一、qsort的介绍&#xff1a; 二、qsort函数的使用 1.qsort排序整形 2.qsort排序字符串 3.qsort排序结…

C语言之——快速排序qsort库函数的讲解

qsort函数C语言编译器函数库自带的排序函数&#xff0c;也叫快速排序函数。之前我写过一篇关于冒泡排序的代码讲解&#xff0c;大家感兴趣的话可以先看一看我对于冒泡排序的讲解。 相比较于冒泡排序&#xff0c;快速排序可以用更加快捷的速度去排列升降序&#xff0c;它的时间复…

C语言qsort函数使用方法大全

文章目录 一、qsort函数简介二、qsort函数常用实例1.比较整型数组2.比较char数组3.比较double数组4.比较字符串4.1按首字母排序4.2按长度排序4,3按字典顺序 5.结构体排序5.1 多级排序 三、qsort深度剖析 一、qsort函数简介 排序方法有很多种&#xff1a;选择排序&#xff0c;冒…

C语言-qsort函数详解

目录 一.qsort函数是什么 二.使用qsort排序-以升序为例 关于void*型指针&#xff1a; 1.整形数组排序 2.字符数组排序 3.字符指针数组排序 4.结构体数组排序 5.浮点型数组排序 三.使用冒泡排序思想模拟实现qsort函数 1.什么是冒泡排序&#xff1a; 2.冒泡排序代码 3. …

C语言qsort()函数的使用(详解)

目录 1.参数含义 1.首元素地址base 2.元素个数num 3.元素大小size 4.自定义比较函数compar 2.使用方式 1.头文件 2.compar的实现 3.整体代码 qsort&#xff08;&#xff09;函数&#xff08;quick sort&#xff09;是八大排序算法中的快速排序&#xff0c;能够排序任意…

虚幻4地形怎么增加层_虚幻周报20200407 | 在家也要好好工作呀~

官方知乎号&#xff1a;虚幻引擎 搜集日期&#xff1a;20200330-20200405 整理编辑&#xff1a; 大钊&#xff0c;小辉辉&#xff0c;马古斯&#xff0c;小帅帅 声明&#xff1a;文档搜集来自网上&#xff0c;难免遗漏&#xff0c;请联系我们投稿和添加关注。该文档版权归整理…

2020年笔记本电脑选购指南

**本文首发微信公众号陈蛋蛋碎碎念&#xff0c;获取更多软件、教程、模板资源&#xff0c;请关注公众号。 最近在群里有小伙伴问关于选购电脑的事&#xff0c;毕竟开学季又要到了。刚好蛋蛋现在又在3C公司工作&#xff0c;所以平时也需要了解这方面的知识&#xff0c;于是就准…

[转]Warzone 2100(战争地带2100)

发行公司&#xff1a;Eidos Interactive 开发公司&#xff1a;Pumpkin Studios 游戏类型&#xff1a;即时战略 游戏语言&#xff1a;英文 发行日期&#xff1a;1999 年4月 系统操作&#xff1a;Win95以上 伴随着这部来自英国开发公司Pumpkin Studios的作品&#xff0c;1999年…

显卡优化软件测试面试,是吹嘘还是真有用?NV游戏优化软件测试

1前言&#xff1a;NVIDIA游戏优化软件试用 英伟达真实热衷为用户提供出色的游戏方案&#xff0c;日前发布了一款GeForce Experience的新软件&#xff0c;本质上是一个基于云端的服务&#xff0c;旨在分析你的硬件并自动调整显示分辨率和游戏设置&#xff0c;以提供更好更优化的…

【转】为什么中国不会有3A游戏

编&#xff1a;王妙一&#xff0c;游戏开发者&#xff0c;代表作《WILL&#xff1a;美好世界》&#xff0c;曾获第二届PlayStation开发者大赛冠军。王妙一大学时就读于清华软件学院图形研究所&#xff0c;本文将从游戏图形技术的发展变迁开始&#xff0c;谈谈3A游戏在现今&…

FPS游戏

FPS 求助编辑百科名片 FPS FPS是第一人称射击类游戏的简称&#xff08;游戏专有名词&#xff09;。 FPS&#xff08;First-Person Shooter Game&#xff09;&#xff1a;第一人称射击游戏 严格来说FPS属于ACT类游戏的一个分支&#xff0c;但和RTS类游戏一样&#xff0c;由于其在…

Centos6.5环境Nginx 1.16.1升级到1.24.0版本

一、背景 2023年4月11日&#xff0c;官方发布了Nginx最新稳定版&#xff0c;版本号为 1.24.0。该版本是基于1.23.x&#xff08;1.23.0 - 1.23.4&#xff09;开发版的Bug修复&#xff0c;以及一些新特性的加入&#xff0c;而形成的稳定版。安全部门扫描后&#xff0c;发现现场不…

C++11 -- 包装器

文章目录 function包装器function包装器的概念function的运用function实例化使用function解决逆波兰表达式 bind包装器bind包装器相关介绍bind绑定函数固定参数 function包装器 function包装器的概念 function包装器,也叫做适配器,它的本质是一个类模板. 例如: 1 template&l…

chatgpt赋能python:Python中撤销的快捷键

Python中撤销的快捷键 在编程中&#xff0c;我们经常需要进行调试&#xff0c;不可避免地会出现一些错误&#xff0c;这时候撤销 (Undo) 功能就显得尤为重要。在 Python 中&#xff0c;我们可以使用一些快捷键来快速撤销&#xff0c;本文将会介绍这些快捷键的使用以及使用它们…