用冒泡排序实现快速排序(qsort函数),指针进阶实例

目录

 

1、qsort函数是什么

2、冒泡排序实现指针进阶

2.1 主函数

2.2 功能函数声明​编辑

2.3 my_qsort函数介绍

2.4 Swap函数

总结


 

1、qsort函数是什么

        qsort函数是c语言自带的函数,其功能是实现快速排序。我们来看一下他的参数和返回值:b1da2fd3888c439a9030cf4b1034276a.png

        以上就是qsort的参数和返回值,可以看到,其返回值是void也就是没有返回值;而参数方面,包括:void* base 这是要排序的数据的起始位置的指针、 size_t num 待排序的数据元素个数、 size_y width 待排序数据元素的大小(单位是字节)、 int(* cmp)(const void* e1,const void* e2) 函数指针变量,其指向一个返回值为int类型,参数为两个void*的指针e1和e2,他们分别指向要排序数据的第一个元素和第二个元素。

        看一个用qsort实现的排序:ac98a28ccd4c4a4eaaebf0f978f44236.png

        我们需要自己定义一个cmp函数,里面设计一个比较函数,e1 和 e2 指向数据的前两个元素,如果设计为:*e1大于*e2时返回正值;*e1等于*e2时返回0;*e1小于*e2时返回负值时,qsort就会实现对数据的升序排列,反之,qsort就会实现降序排列。因此,我们发现,qsort实现的功能其实取决于我们如何去设计cmp函数。此外,qsort可以比较不仅限于整型数据的大小,还可以比较字符串等等各种类型的大小,其规则和整型相同,都是取决于如何去设计cmp函数。

        好了,讲到这我们大致了解了qsort函数,现在,我们将用冒泡排序去实现qsort的功能。这样的练习有助于我们更好地了解和运用指针,实现我们对c语言的进阶。

2、冒泡排序实现快速排序

        先看看最终代码:

#include <stdio.h>void my_qsort(void* base, int num, int width, int (*cmp)(const void* e1, const void* e2));
void Swap(char* e1, char* e2, int width);
int cmp(const void* e1, const void* e2);int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9 };int sz = sizeof(arr) / sizeof(arr[0]);my_qsort(arr,sz,sizeof(int),cmp);int i = 0;for (i = 0;i < sz;i++){printf("%d ", arr[i]);}return 0;
}void my_qsort(void* base, int num, int width, int (*cmp)(const void* e1, const void* e2))
{int i = 0;for (i = 0;i <num-1;i++){int flag = 1;int j = 0;for (j = 0;j < num - 1 - i;j++){if (cmp((char*)base + width * j, (char*)base + width * (j + 1)) < 0){//交换Swap((char*)base + width * j, (char*)base + width * (j + 1),width);}}}
}void Swap(char* e1, char* e2, int width)
{int i = 0;int c = 0;for (i = 0;i < width;i++){c = *(e1 + i);*(e1 + i) = *(e2 + i);*(e2 + i) = c;}
}int cmp(const void* e1, const void* e2)
{return *((int*)e1) - *((int*)e2);
}

效果:

edc583e62d9441fe9f1c97eedb63cf4d.png

可见确实模拟出了qsort的效果。

一步步分析:

2.1 主函数

int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9 };int sz = sizeof(arr) / sizeof(arr[0]);my_qsort(arr,sz,sizeof(int),cmp);int i = 0;for (i = 0;i < sz;i++){printf("%d ", arr[i]);}return 0;
}

        主函数主要是arr数组的定义,求其长度sz,引用my_qsort函数和打印排序后的函数。没有需要重点讲的。

        接下来介绍所运用到的功能函数:

2.2 功能函数声明3a1eae1069d446b294829609d3db822f.png

        这里包括了三个函数,my_qsort就是用冒泡排序模拟实现qsort的函数,Swap函数是用来交换e1和e2的函数,cmp就是正常qsort中我们需要自己设定的函数,可以通过改变cmp的内容实现不同效果的排序。其中cmp在上面已经介绍过了所以下面我只重点介绍my_qsort函数和Swap函数。

2.3 my_qsort函数介绍

d97290f07b964adfa717f572dfebfc0d.png

        首先要明白,这个函数的主要思想其实是一个冒泡排序。只不过在正常冒泡排序的交换过程我们用了Swap函数代替。

        重点来了,来看看其中这两行的代码:310df004c47141be8b8dd361306e2b1c.png

        这里我们将原本void类型的代码转化为了cahr*,这是因为,我们模拟的qsort是一个可以对任何数据进行排序的函数,不仅限于int类型,所以,我们要想一个办法能够用指针去指向任意大小的数据,我们考虑的就是char*类型,因为我们传参的时候将元素的大小width传了过来,这样,我们定义了char*类型的指针(1字节),只需要用i*width就可以指向后i个数据;反之,如果不用char*类型的话,其他类型的指针步长本身都不为1字节,,这样加上i无法确定指针指向了哪个数据。

        下面,来讲解一下Swap函数:

2.4 Swap函数

928c87de5dd048328b0d0f37f608fb98.png

        Swap函数实现的是大小为width的两个元素的互换,由于我们指针e1和e2为char类型,所以,想要完全互换的话,需要对指针后width个内容都进行互换,因此我们写了如此一个循环进行互换。

总结

        以上,就是用冒泡排序实现qsort函数的模拟了,它不仅可以对整型数据进行排序,还可以对任意类型数据进行排序,其中运用到了函数指针,也要求编程者对函数有一定深刻的理解。了解好原理,自己动手去完成这样一个函数模拟,我相信,你对指针的的理解会上升一个台阶。

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot+flowable 使用方式

创建flowble制定流程图 登录flowalbe 制定流程图 进入建模器应用程序 创建流程图 分配用户 下载流程图 使用springboot 调用flowable /*** 导入流程图老师流程*/Testvoid startTeacherApprover(){Deployment deploy repositoryService.createDeployment().addClasspathRes…

2024年天津市安全员C证证模拟考试题库及天津市安全员C证理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年天津市安全员C证证模拟考试题库及天津市安全员C证理论考试试题是由安全生产模拟考试一点通提供&#xff0c;天津市安全员C证证模拟考试题库是根据天津市安全员C证最新版教材&#xff0c;天津市安全员C证大纲整理…

linux内核视角看零拷贝

一、什么是零拷贝&#xff1f; 在很多性能优化方案中都有提到零拷贝&#xff0c;零拷贝到底是怎么回事&#xff0c;是真的没有数据的拷贝吗&#xff1f;零拷贝&#xff08;Zero-copy&#xff09;是一种数据传输技术&#xff0c;旨在减少数据在内核态和用户态之间的复制操作。其…

计算机网络概论和数据通信基础

文章目录 计算机网络概论从物理构成上看&#xff0c;计算机网络包括硬件、软件和协议三大部分计算机网络的功能组成计算机网络的分类网络体系结构分层与体系结构接口、协议和服务数据传送单位OSI模型TCP/IP模型 数据通信基础数字信号调制为模拟信号正交振幅调制QAM 模拟数据编码…

二叉树基本概念与遍历

什么是二叉树 二叉树不同于别的树&#xff0c;因为他每个节点最多只有两个子节点&#xff0c;而别的树可以有无数个子节点。 所以二叉树就是只最多只有两个子节点的树&#xff0c;一个子节点叫右子节点&#xff0c;另一个子节点叫左子结点 而他们的上一层就是父子节点&#xf…

航班进出港|航班进出港管理系统|基于springboot航班进出港管理系统设计与实现(源码+数据库+文档)

航班进出港管理系统目录 目录 基于springboot航班进出港管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 5、航班信息管理 &#xff08;1&#xff09; 航班信息管理 &#xff08;2&#xff09;起飞降落申请管理 &#xff08;3&#xff09;公告管理 &…

城市智慧驿站是什么?城市智慧驿站有哪些功能

城市智慧驿站作为一种创新性的社会配套设施&#xff0c;开始在多个城市落地使用&#xff0c;引起了社会的关注。 城市智慧驿站是什么&#xff1f;城市智慧驿站是在智慧城市的背景下&#xff0c;城市智慧驿站智慧公厕成为了一种创新性的社会配套建筑。作为景观式模块化建筑&…

UE蓝图 分支(Branch)节点和源码

系列文章目录 UE蓝图 Get节点和源码 UE蓝图 Set节点和源码 UE蓝图 Cast节点和源码 UE蓝图 分支(Branch)节点和源码 文章目录 系列文章目录一、分支节点功能二、分支节点用法三、分支节点使用场景四、分支节点实现过程五、分支节点相关源码 一、分支节点功能 在Unreal Engine&a…

Mysql数据库主从集群从库Slave因为RelayLog过多过大引起服务器硬盘爆满生产事故实战解决

Mysql数据库主从集群从库slave因为RelayLog过多过大引起从库服务器硬盘爆满生产事故实战解决 一、MySQL数据库主从集群概念 MySQL数据库主从集群是一种高可用性和读写分离的数据库架构&#xff0c;它基于MySQL的复制&#xff08;Replication&#xff09;技术来同步数据。在主…

【Kotlin】Kotlin流程控制

1 选择结构 Kotlin 中选择结构主要包含 if -else、when 语句&#xff0c;并且可以返回结果。 1.1 if-else 1.1. 条件选择 fun main() {var score 85if (score > 90) {println("优秀")} else if (score > 80) {println("良好")} else if (score &…

信息安全法律法规体系

信息安全法律法规体系 我国信息安全法规体系可以分为4层。 法律层面具体对应的法律、法规一般性法律规定宪法、国家安全法、国家秘密法、治安管理处理条例等虽然没有专门针对信息安全的条款,但约束了信息安全相关的行为规范和惩罚信息网络犯罪的法律《中华人名共和国刑法》《…

MySQL篇之主从同步原理

一、原理 MySQL主从复制的核心就是二进制日志。 二进制日志&#xff08;BINLOG&#xff09;记录了所有的 DDL&#xff08;数据定义语言&#xff09;语句和 DML&#xff08;数据操纵语言&#xff09;语句&#xff0c;但不包括数据查询&#xff08;SELECT、SHOW&#xff09;语句。…

19-树-填充每个节点的下一个右侧节点指针 II

这是树的第19篇算法&#xff0c;力扣链接。 给定一个二叉树&#xff1a; struct Node {int val;Node *left;Node *right;Node *next; } 填充它的每个 next 指针&#xff0c;让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点&#xff0c;则将 next 指针设置为 NULL 。…

继ChatGPT后的又一王炸!Sora模型解析与体验通道

前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff1a;https://www.captainbed.cn/z ChatGPT体验地址 文章目录 前言OpenAI体验通道Spacetime Latent Patches 潜变量时空碎片, 建构视觉语言系统…

“薪”的一年程序员裁员潮技术变革情况下 程序员就业机会在哪里?

引言&#xff1a;一对来自中国的工程师夫妻在美国的不幸身亡&#xff0c;疑似与谷歌的裁员有关&#xff0c;这一事件再次引发了人们对技术变革下裁员对程序员影响的关注。 一、针对裁员潮的一些看法 在我看来&#xff0c;技术变革对程序员的影响是双面的。一方面&#xff0c;…

代码随想录算法训练营day16

题目&#xff1a;104.二叉树的最大深度、111.二叉树的最小深度、222.完全二叉树的节点个数 参考链接&#xff1a;代码随想录 104.二叉树的最大深度 思路&#xff1a;上次是用层序遍历的思路做过。这次想一点不一样的思路&#xff0c;对于一个二叉树的最大深度其实即为其两个…

【Python机器学习】详解Python机器学习进行时间序列预测

&#x1f517; 运行环境&#xff1a;Python &#x1f6a9; 撰写作者&#xff1a;左手の明天 &#x1f947; 精选专栏&#xff1a;《python》 &#x1f525; 推荐专栏&#xff1a;《算法研究》 &#x1f510;#### 防伪水印——左手の明天 ####&#x1f510; &#x1f497; 大家…

C++:const关键字

一、const成员变量(常成员变量) 1、只能使用初始化列表对常成员变量进行初始化&#xff1b; 2、常成员变量可以被访问&#xff0c;但是不能被修改&#xff1b; 3、类中所有构造函数都必须在初始化列表对常成员函数进行初始化(包括拷贝构造&#xff0c;移动构造)。 声明&am…

加固平板电脑在无人机的应用|亿道三防onerugged

无人机技术的快速发展已经在许多领域展现出巨大潜力&#xff0c;而加固平板电脑的应用在无人机领域中扮演着重要角色。 首先&#xff0c;加固平板电脑在无人机探测设备中发挥着关键作用。无人机探测设备通常需要实时传输高清图像和数据&#xff0c;以支持各种监测、勘测和检测…

蓝桥杯DP算法——背包问题(C++)

目录 一、01背包问题 二、完全背包问题 三、多重背包问题 四、多重背包问题&#xff08;优化版&#xff09; 五、分组背包问题 一、01背包问题 01背包问题就是有N件物品&#xff0c;一个空间大小为V的背包&#xff0c;每个物品只能使用一次&#xff0c;使得背包中所装物品…