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.婴幼儿配方乳粉的产品配方应当经()部门注册。…...
基于事件驱动与SSH的轻量级实时文件同步工具Pynchy详解
1. 项目概述:一个轻量级、高可用的文件同步守护进程最近在折腾个人服务器和开发环境之间的文件同步,试过不少方案,要么太重,要么配置复杂,要么实时性不够。直到我发现了crypdick/pynchy这个项目,它用 Pytho…...
Gemini自动生成PPT实战手册:从零输入到专业演示文稿,3步完成95%的幻灯片工作流
更多请点击: https://intelliparadigm.com 第一章:Gemini自动生成PPT的核心原理与能力边界 Gemini 生成 PPT 的本质并非传统模板填充,而是基于多模态理解与结构化内容重构的端到端推理过程。其核心依赖于对用户输入(文本、大纲、…...
uni-number-box深度解析:从基础属性到高级双向绑定实战
1. uni-number-box基础入门:从零开始玩转数字输入框 第一次接触uni-number-box时,我也觉得这不就是个简单的数字加减控件吗?直到在电商项目中真正用起来,才发现这个看似简单的组件藏着不少门道。uni-number-box是uni-app框架提供的…...
9 款 AI 写论文哪个好?2026 深度实测|虎贲等考 AI 凭真文献 + 真实图表 + 全流程实证,稳坐毕业论文首选
毕业季高频提问:9 款 AI 写论文哪个好?市面上工具看似大同小异,实则在文献真实性、实证图表、全流程覆盖、学术合规上差距巨大。通用大模型文献造假、普通工具无实证能力、小众平台功能残缺,选错轻则反复改稿,重则查重…...
GD32F303硬件I2C实战:手把手教你用AT24C02 EEPROM存储和读取设备配置参数
GD32F303硬件I2C实战:构建工业级参数存储系统 在嵌入式设备开发中,系统参数的持久化存储是个看似简单却暗藏玄机的需求。想象一下,当你的智能温控器经历突然断电后,所有用户设置的日程和偏好全部归零——这种体验足以让产品口碑崩…...
STM32F103C8T6驱动5V LCD1602,开漏输出+上拉电阻的硬件连接与代码避坑指南
STM32F103C8T6驱动5V LCD1602的硬件设计与代码实战指南 当3.3V的STM32遇到5V供电的LCD1602模块时,电平不匹配问题常常让初学者头疼不已。本文将深入解析开漏输出配合上拉电阻的解决方案,通过硬件原理分析、示波器实测对比和完整代码示例,带你…...
揭秘网易NeoX引擎:用unnpk工具深度探索游戏资源宝库
揭秘网易NeoX引擎:用unnpk工具深度探索游戏资源宝库 【免费下载链接】unnpk 解包网易游戏NeoX引擎NPK文件,如阴阳师、魔法禁书目录。 项目地址: https://gitcode.com/gh_mirrors/un/unnpk 你是否曾好奇《阴阳师》、《魔法禁书目录》等网易热门游戏…...
JEB Pro 5.40 (macOS, Linux, Windows) - Android 反编译器和调试器
JEB Pro 5.40 (macOS, Linux, Windows) - 逆向工程平台 Reverse Engineering for Professionals. 请访问原文链接:https://sysin.org/blog/jeb/ 查看最新版。原创作品,转载请保留出处。 作者主页:sysin.org JEB Decompiler JEB 是逆向工程…...
告别疲劳计算烦恼:用nCode DesignLife搞定汽车悬架非线性载荷分析(附信号处理技巧)
告别疲劳计算烦恼:用nCode DesignLife搞定汽车悬架非线性载荷分析(附信号处理技巧) 悬架系统作为汽车底盘的核心部件,其疲劳寿命直接关系到整车可靠性与安全性。但在实际工程分析中,工程师们常常被一个棘手问题困扰&am…...
别再只盯着原理图了!用Python+OpenCV动手模拟激光三角测距(斜射/直射对比)
用PythonOpenCV模拟激光三角测距:斜射与直射的实战对比 激光三角测距技术听起来高大上,但真正理解它的精髓往往需要跳出公式推导的泥潭。作为一名长期在工业检测领域摸爬滚打的技术人员,我发现用代码模拟物理过程是最有效的学习方式。本文将…...
