qsort函数的应用以及模拟实现

前言
🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨
🐻推荐专栏: 🍔🍟🌯 c语言进阶
🔑个人信条: 🌵知行合一
🍉本篇简介:>:介绍库函数qsort函数的模拟实现和应用
金句分享:
✨追光的人,终会光芒万丈.✨
目录
- 前言
- 一、qsort函数介绍
- 二、qsort函数的应用
- 1.整形数组排序
- 2.浮点型数组排序
- 3.字符型排序
- 4.结构体数组排序
- 三、qsort模拟实现(采用冒泡排序模拟)
- 第一步:冒泡函数的参数
- 第二步:比较元素的的方法
- 第三步:交换函数
一、qsort函数介绍
库函数查询网站(建议使用旧版本查询)

头文件:<stdlib.h>

功能介绍:
使用函数确定顺序,对指向的数组的元素进行排序,每个元素的长度以字节为单位。
此函数使用的排序算法通过调用指定的函数(要自己定义元素比较方式函数传给qsort)并将指向元素的指针作为参数来比较元素.
该函数不返回任何值,而是通过按定义重新排序数组元素来修改指向的数组的内容。
参数介绍:
| 参数1(void* base) | 要排序的数组首地址 |
|---|---|
| 参数2(size_t num) | 数组中的元素个数。 |
| 参数3(size_t size) | 数组中每个元素的大小(以字节为单位)。 |
| 参数4 ( int (compar)(const void,const void*)) | 指向数组中元素比较方式的函数指针 |
二、qsort函数的应用
1.整形数组排序
#include <stdio.h>
#include <stdlib.h>
//注意,由于qsort排序时,并不知道要排序的元素是何种类型,
//所以自定义比较函数的参数都暂时是void*要强制类型转化为对应类型才可以使用.
int int_sort(const void* e1, const void* e2)//自定义整形元素比较方式函数
{return *(int*)e1 - *(int*)e2;
}
int main()
{int arr1[10] = { 4,6,1,7,8,2,9,10,3,5 };int sz1 = sizeof(arr1) / sizeof(arr1[0]);//计算元素个数qsort(arr1, sz1, sizeof(arr1[0]), int_sort);//整形排序int i = 0;for (i = 0; i < sz1; i++)//整形打印{printf("%d ", arr1[i]);}return 0;
}
运行结果:
1 2 3 4 5 6 7 8 9 10
2.浮点型数组排序
//浮点型数组排序
#include <stdio.h>
#include <stdlib.h>
int double_sort(const void* e1, const void* e2)//浮点型比较
{
//注意要强制转化为相对于的类型,然后解引用比较.int ret = 0;if ((*(double*)e1) - (*(double*)e2) > 0){ret = 1;//前面的数比后面大时返回整数}else ret = -1;//后面数大返回负数;return ret;//两个数相等返回0;
}
int main()
{double arr2[6] = {3.41, 9.45, 4.78, 3.67, 2.9, 7.36 };int sz2 = sizeof(arr2) / sizeof(arr2[0]);//计算数组元素个数qsort(arr2, sz2, sizeof(arr2[0]), double_sort);int i = 0;for (i = 0; i < sz2; i++)//浮点型数组打印{printf("%5.2lf ", arr2[i]);}return 0;
}
运行结果:
2.90 3.41 3.67 4.78 7.36 9.45
3.字符型排序
//字符型数组排序
#include <stdio.h>
#include <stdlib.h>
int char_sort(const void* e1, const void* e2)//字符型比较
{return (*(char*)e1) - (*(char*)e2);
}
int main()
{char arr3[10] = { 'd','g','b','a','e','i','h','c','j','f' };int sz3 = sizeof(arr3) / sizeof(arr3[0]);//计算元素个数qsort(arr3, sz3, sizeof(arr3[0]), char_sort);int i = 0;for (i = 0; i < sz3; i++)//字符型打印{printf("%c ", arr3[i]);}
}
运行结果:
a b c d e f g h i j
4.结构体数组排序
strcmp函数用于比较字符串的,它的比较方式是比较字符的ASCII码值,并不是长度,后续在库函数模拟篇会讲到.
//结构体排序
#include <stdio.h>
#include <stdlib.h>
struct student//创建结构体类型
{char name[15];char sex[3];int age;float stature;
};
typedef struct student sc;//对结构体类型重命名
int sort_age(const void* e1, const void* e2)//按年龄排序
{return (((sc*)e1)->age - ((sc*)e2)->age);
}
int sort_name(const void* e1, const void* e2)//按姓名排序
{return strcmp(((sc*)e1)->name, ((sc*)e2)->name);
}
int main()
{sc arr4[5] = { {"chu jie niu","男",20,1.73f},{"xiao wang","男",19,1.68f},{"qing niao","女",21,1.59f},{"wao shu li","男",16,1.83f},{"peng hu wan","男",15,1.81f} };int sz4 = sizeof(arr4) / sizeof(arr4[0]);//qsort(arr4, sz4, sizeof(arr4[0]), sort_age);qsort(arr4, sz4, sizeof(arr4[0]), sort_name);int i = 0;printf("姓名 性别 年龄 身高\n");for (i = 0; i < sz4; i++){printf("%-12s %-5s %-5d %-5.2fm\n", arr4[i].name, arr4[i].sex, arr4[i].age, arr4[i].stature);}return 0;
}
运行结果:
姓名 性别 年龄 身高
chu jie niu 男 20 1.73 m
peng hu wan 男 15 1.81 m
qing niao 女 21 1.59 m
wao shu li 男 16 1.83 m
xiao wang 男 19 1.68 m
三、qsort模拟实现(采用冒泡排序模拟)
复习一下冒泡排序吧!
void bubble_sort(int* arr, int sz)//冒泡排序
{int i = 0, j = 0;for (i = 0; i < sz - 1; i++){for (j = 0; j < sz - 1 - i; j++){if (arr[j] > arr[j + 1]){int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;}}}
}
int main()
{int arr[10] = { 4,7,1,8,2,3,9,10,5,6 };int sz = sizeof(arr) / sizeof(arr[0]);//计算元素个数bubble_sort(arr, sz);for (int i = 0; i < sz; i++)//数组打印{printf("%d ",arr[i]);}return 0;
}
qsort模拟实现(采用冒泡排序模拟实现)
第一步:冒泡函数的参数
首先,要修改的是冒泡排序函数的参数.
void bubble_sort(void * arr, size_t num, size_t width, int (cmp)(const void, const void*))
这四个参数的含义上面介绍qsort参数时有介绍.
需要注意的是,qsort函数事先并不知道要传过来的数组是何种类型,所以先用void*接收.
补充知识:
void*可以接收任何类型的变量,但是并不能直接使用,要强制类型转化为对应类型使用.
第二步:比较元素的的方法
if (arr[j] > arr[j + 1])
语句中的arr[j]和arr[j+1]有两点需要注意.
由于事先不知道类型
1.要先将arr强制类型转化为char*,因为一个字节是类型的最小单位,这时width就发挥作用了.
arr[j]转化为 (char*)arr + j * width
arr[j+1]转化为 (char*)arr + (j + 1) * width

2.元素的比较方式不再是单一的相减就可以,这里就用到了自定义函数,元素的比较方式函数.
if (cmp((char*)arr + j * width, (char*)arr + (j + 1) * width) > 0)
第三步:交换函数
对于这样只能实现整形的交换方式,肯定是不行的.
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
修改为:用char*类型修改交换
swap(char* e1, char* e2, size_t sz)//交换函数
{//由于qsort函数事先不知道要比较的元素是何种类型,所以用最小单位一个字节来交换.//sz代表元素的所占字节大小int i = 0;char p = 0;for (i = 0; i < sz; i++){p = *(e1 + i);*(e1 + i) = *(e2 + i);*(e2 + i) = p;}
}
最后展示全部代码:
#include <stdio.h>
#include <stdlib.h>
struct student//创建结构体类型
{char name[15];char sex[3];int age;float stature;
};
typedef struct student sc;//对结构体类型重命名
int sort_age(const void* e1, const void* e2)//按年龄排序
{return (((sc*)e1)->age - ((sc*)e2)->age);
}
int sort_name(const void* e1, const void* e2)//按姓名排序
{return strcmp(((sc*)e1)->name, ((sc*)e2)->name);
}
int int_sort(const void* e1, const void* e2)//整形比较
{return *(int*)e1 - *(int*)e2;
}
swap(char* e1, char* e2, size_t sz)//交换函数
{//由于qsort函数事先不知道要比较的元素是何种类型,所以用最小单位一个字节来交换.//sz代表元素的所占字节大小int i = 0;char p = 0;for (i = 0; i < sz; i++){p = *(e1 + i);*(e1 + i) = *(e2 + i);*(e2 + i) = p;}
}
//最后一个参数是函数指针,指向两个元素的比较方法这个函数
void bubble_sort(void * arr, size_t num, size_t width, int (*cmp)(const void*, const void*))
{int i = 0, j = 0;for (i = 0; i < num-1; i++){for (j = 0; j < num - 1 - i; j++){if (cmp((char*)arr + j * width, (char*)arr + (j + 1) * width) > 0){swap((char*)arr + j * width , (char*)arr + (j + 1) * width,width);}}}
}int main()
{int arr[10] = { 4,7,1,8,2,3,9,10,5,6 };int sz = sizeof(arr) / sizeof(arr[0]);//计算元素个数bubble_sort(arr,sz,sizeof(arr[0]),int_sort);for (int i = 0; i < sz; i++)//数组打印{printf("%d ",arr[i]);}printf("\n");sc arr4[5] = { {"chu jie niu","男",20,1.73f},{"xiao wang","男",19,1.68f},{"qing niao","女",21,1.59f},{"wao shu li","男",16,1.83f},{"peng hu wan","男",15,1.81f} };int sz4 = sizeof(arr4) / sizeof(arr4[0]);qsort(arr4, sz4, sizeof(arr4[0]), sort_age);//qsort(arr4, sz4, sizeof(arr4[0]), sort_name);int i = 0;printf("姓名 性别 年龄 身高\n");for (i = 0; i < sz4; i++){printf("%-12s %-5s %-5d %-5.2fm\n", arr4[i].name, arr4[i].sex, arr4[i].age, arr4[i].stature);}return 0;
}
运行结果:
1 2 3 4 5 6 7 8 9 10
姓名 性别 年龄 身高
peng hu wan 男 15 1.81 m
wao shu li 男 16 1.83 m
xiao wang 男 19 1.68 m
chu jie niu 男 20 1.73 m
qing niao 女 21 1.59 m
qsort函数用冒泡排序的模拟实现,就讲到这里了,如果文章有错误或者不理解的地方,欢迎私信牛牛,互相交流,互相学习.
最后,如果文章对大家有帮助的话,求一波三连吧!
💗💗💗886

相关文章:
qsort函数的应用以及模拟实现
前言 🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨ 🐻推荐专栏: 🍔🍟🌯 c语言进阶 🔑个人信条: 🌵知行合一 🍉本篇简介:>:介绍库函数qsort函数的模拟实现和应用 金句分享: ✨追…...
【iobit 软件】家族系列 - 正版激活码
装机必备iobit系列软件 - 激活码获取看最后 第一款、Advanced SystemCare 16 您需要的人工智能驱动的PC优化器,以释放磁盘空间,加速PC并保护在线隐私。 功能特点: 1. 系统清理与优化:通过清除系统垃圾文件、注册表信息、无用文…...
ACM-大一训练第三周(Floyd算法+并查集算法专题训练)
🚀write in front🚀 📝个人主页:认真写博客的夏目浅石.CSDN 🎁欢迎各位→点赞👍 收藏⭐️ 留言📝 📣系列专栏:ACM周训练题目合集.CSDN 💬总结:…...
taobao.item.sku.update( 更新SKU信息 )
¥开放平台免费API必须用户授权 *更新一个sku的数据 *需要更新的sku通过属性properties进行匹配查找 *商品的数量和价格必须大于等于0 *sku记录会更新到指定的num_iid对应的商品中 *num_iid对应的商品必须属于当前的会话用户 公共参数 请求地址: HTTP地址 http://gw.…...
ros2创建一个工程
第一步:创建src目录 $ mkdir ros2-demo $ cd ros2-demo/ $ mkdir src $ cd src/第二步:创建功能包cd src$ ros2 pkg create --build-type ament_cmake ros2_demo --dependencies rclcpp std_msgsros2 pkg create --build-type ament_python learning_pkg…...
【力扣】stack容器的探索之有效的括号
作者:狮子也疯狂 专栏:《算法详解》 愿你生如夏花之绚烂,幸运永远与你相伴,疯狂常在。 目录一. 🦁 Stack容器的来历1.1 操作栈的方法二. 🦁 Stack的使用2.1 题目2.2 分析2.3 详细算法实现2.4 力扣AC截图三…...
【Elsevier出版社】中科院2区,SCIEEI 双检,已有发表案例,3个月左右录用
1区智能传感器类SCIE&EI 【期刊简介】IF:5.0-6.0,JCR1区,中科院2区,SCI&EI 双检,正刊 【参考周期】3个月左右录用 【截稿日期】2023.5.30 【征稿领域】有关人工智能与传感器的相关研究均可 包括但不限于&#…...
基于明道云平台重建医院管理流程
一、龙华区医疗信息化建设情况 首先,给大家介绍一下龙华区医疗信息化建设的情况,龙华区位于深圳市的中部,目前下属3家公立医院,2家公共卫生机构。2017年,龙华区提出了建设智慧龙华总体框架方案,龙华区卫生…...
【蓝桥杯嵌入式】STM32定时器的配置,解析预分频系数和重装载值与时钟频率的关系
🎊【蓝桥杯嵌入式】专题正在持续更新中,原理图解析✨,各模块分析✨以及历年真题讲解✨都在这儿哦,欢迎大家前往订阅本专题,获取更多详细信息哦🎏🎏🎏 🪔本系列专栏 - 蓝…...
ChatGPT API 低价上线,开发者可以人手一个了?
千呼万唤,ChatGPT API来了! 不仅首发,价格居然还有惊喜,0.002美元/每1000 token,并将价格降低90%,直接打了1折。OpenAI官方还表示,gpt-3.5-turbo目前的版本代号是gpt-3.5-turbo-0301࿰…...
品牌营销策略 | 科学经营合作伙伴关系的5个要素
在管理众多的合作伙伴项目时,企业会遇到很多的问题,比如,数据信息分散凌乱、手动操作繁琐重复和处理环节粗放等。这将耗费公司大量的人力物力,严重影响大数据的综合分析和利用。因此,企业要科学管理好企业的合作伙伴关…...
【剑指offer-C++】JZ20:表示数值的字符串
【剑指offer-C】JZ20:表示数值的字符串题目描述解题思路题目描述 描述:请实现一个函数用来判断字符串str是否表示数值(包括科学计数法的数字,小数和整数)。 科学计数法的数字(按顺序)可以分成以下几个部分…...
【NLP相关】深度学习领域不同编程IDE对比
❤️觉得内容不错的话,欢迎点赞收藏加关注😊😊😊,后续会继续输入更多优质内容❤️👉有问题欢迎大家加关注私戳或者评论(包括但不限于NLP算法相关,linux学习相关,读研读博…...
定制ubuntu的docker镜像
ssh登录jdkmavenvimpingcurlFROM ubuntu:22.04RUN apt-get updateRUN apt-get install -y \vim \inetutils-ping \openssh-server \curl \openjdk-8-jdk \mavenRUN mkdir /var/run/sshdRUN echo root:root |chpasswdRUN sed -ri s/^#?PermitRootLogin\s.*/PermitRootLogin yes…...
我的 System Verilog 学习记录(8)
引言 本文简单介绍 SystemVerilog 的接口。 前文链接: 我的 System Verilog 学习记录(1) 我的 System Verilog 学习记录(2) 我的 System Verilog 学习记录(3) 我的 System Verilog 学习记…...
详解JAVA字节码
目录 1.概述 2.字节码文件构成 2.1.魔数 2.2.版本号 2.3.常量池 2.4.访问标志 2.5.索引 2.6.字段表 2.7.方法表 3.字节码指令 3.1.概述 3.2.指令分类 3.2.1.加载存储指令 3.2.2.运算指令 3.2.3.其他指令 3.3.完整指令工作流程 4.字节码保护 1.概述 以往的编程…...
前端利用emailjs发送邮件
最近有一个需求,前端发送一个form表单到一个邮箱,找了一圈发现emailjs还不错就使用他了。首先emailjs官网注册一个账号注册完之后创建一个邮件服务(我这里使用的是谷歌邮箱)链接谷歌邮箱账户 然后创建服务接下来就要创建一个邮件的…...
16 Nacos服务端服务注册源码分析
Nacos服务端服务注册源码分析 服务端调用接口 我们已经知道客户端在注册服务的时候实际上是调用的NamingService.registerInstance这个方法来完成实例的注册,而且在最后我们也告诉了大家实际上从本质上讲服务注册就是调用的对应接口nacos/v1/ns/instanceÿ…...
Spring Boot2中如何优雅地个性化定制Jackson
概述 本文的编写初衷,是想了解一下Spring Boot2中,具体是怎么序列化和反序列化JSR 310日期时间体系的,Spring MVC应用场景有如下两个: 使用RequestBody来获取JSON参数并封装成实体对象;使用ResponseBody来把返回给前…...
2023年全国最新食品安全管理员精选真题及答案11
百分百题库提供食品安全管理员考试试题、食品安全员考试预测题、食品安全管理员考试真题、食品安全员证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 101.婴幼儿配方乳粉的产品配方应当经()部门注册。…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...
深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向
在人工智能技术呈指数级发展的当下,大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性,吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型,成为释放其巨大潜力的关键所在&…...
水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关
在水泥厂的生产流程中,工业自动化网关起着至关重要的作用,尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关,为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多,其中不少设备采用Devicenet协议。Devicen…...
【堆垛策略】设计方法
堆垛策略的设计是积木堆叠系统的核心,直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法,涵盖基础规则、优化算法和容错机制: 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则: 大尺寸/重量积木在下…...
