C语言----冒泡排序进阶
冒泡排序大家应该到写过吧。但大家可能知道到的冒泡排序有两种方法。而我呢,最近学习到了另外一种方法,现在知道三种方法了。所以想与大家分享一下。但是缺点是第三种是第二种的自实现版。第一种就是我们平常写的普通冒泡排序。第二种就是qsort。第三种就是my_qsort。好那么我们就这三种冒泡排序来讲述。
普通冒泡
大家学习肯定都是先易后难。我们也就先从大家最先学习的冒泡排序开始。当然我不知道,大家对于最常见的冒泡排序是如何理解的,我就先讲解我自己对于冒泡排序的见解。我是这样认为的。因为需要冒泡排序的话,那么就是需要排序后的数组依照升序或者降序来排序,那么我就有双循环语句来写。例如一个数组有10个元素,且下标为0的元素是最大的元素的话。那么我用下标0的元素依次与下一个元素比较,大于的话,用一个零时变量来使这两个值交换。一直到下标为9的时候停止。然后进行下一个循环。当然,因为我已经遍历了一遍确定现在的下标为9的元素是数组中最大的元素所以我们在下一次遍历的时候就可以减少对最后的元素比较。好,那么接下来我们就用代码来更加详细的讲解。
不知道我的代码与大家想的是否有太多的不同之处。或者大家认为这样的代码还有地方可以简洁,大家可以在下方评论区不腻赐教。但其实大家看了上面的代码是否觉得有点啰嗦且繁琐啊。如果我们运气不好的话。这个代码我们要遍历36遍。空间复杂度是否有时候不好满足呀。并且我们如果后面改了,不用整型数组,我们有char类型数组的话。这个代码是不是就不能直接使用了。当然我们可以依照这个模板写一个char类型的冒牌排序,但是大家是否觉得再写一个的话,是否就有点太麻烦了。那是否有这个简单且适应其他类型排序的排序方法嘞。嘿,还真有。在c语言编辑的时候,编辑者就想到了,后面的使用可能会需要对数组进行排序,那么我就写一个库函数吧,后面额人直接使用库函数再添加一些关键数据就可以排序了。这就是我接下里想与大家分享的知识。库函数qsort。
库函数qsort
大家也知道了我们接下来要讲的是库函数qsort。那我们先来了解qsort是什么,由什么构成的
void qsort(void *base,size_t nmemb,size_t size,int (*compar)(const void *, const void *));
头文件:<stdlib.h> qsort()函数的功能是对数组进行排序,数组有nmemb个元素,每个元素大小为size。打大家看上面这个肯定对qsort还是不了解。那么我们直接用代码来实践解决。
当然因为是库函数所以头文件肯定是不能少的,我只是在前面的时候写过了没有照下来,大家在使用的时候记得写出来就可以了。大家看了后,可能会想,不是说可以适用于所有类型吗。你这不是char类型吗?但是大家可以看一下,我在判断大小的时候用的是void*来接收的。为什么用void*来接收嘞。这就不得不说void*的作用了。void大家都知道,无类型,那么无类型的话是不是所有类型的可以接收,相当于一个五边形战士,你来什么对手我都可以打败。但是大家需要注意到,最大的对手自己,所有void*不可以进行就算改变。它只能接收,不能进行改变。这样大家知道我们我在判断大小的时候,返回值的时候要将p1和p2强转为char类型了吧。所有qsort可以排序任意类性数组真相大白了。我们需要在给qsort传递判断大小的时候需要用void*来接收(因为void*可以接收任意类型)。然后返回的时候再强转为数组的类型(使用者肯定知道自己需要排序的数组是什么类型),这样qsort就完美的写出了。当然我可以在写一个int类型的排序,只需要在这个代码上面修改一些部分。
大家可以对照上面的图片,我们写另外一个类型的排序数组,不需要完全重写一个代码,我们只需要将一些关键的类型改变就可以了 。
注:qsort比较大小是使用的ascll码来比较的!!!
自实现qsort
当我们知道qsort如何使用了后,肯定不能止步于此呀,我们要完全将这个函数吃透的话,最好直接写一个代码来实现这个功能。那么接下来我们写的就是my_qsort。大家学习了上面的代码后,就是如果自己写一个的话,需要干什么。我们就以上面的代码来。我们先写,然后总结:
int daxiao(const void *p1,const void *p2)//判断大小
{return *(int*)p1 - *(int*)p2;
}
void jiaohuan(char*p1, char*p2, size_t haa)//交换值,char类型是为了方便交换,多循环几次就交换全部了
{for (int a = 0; a < haa; a++){char count = *p1;*p1 = *p2;*p2 = count;p1++;p2++;}
}
void my_qsort(void*arr,size_t sz,size_t ha,int (*pf)( void *p1,void *p2))
{for (int a = 0; a < sz - 1; a++){for (int y = 0; y < sz - 1 - a; y++){if (pf((char*)arr + y *ha, (char*)arr + (y + 1)*ha)>0)//判断,如果大于就交换小于不管jiaohuan((char*)arr + y*ha, (char*)arr + (y + 1)*ha,ha);}}
}
void dayin(int *arr, int sz)//打印结果
{for (int yy = 0; yy < sz; yy++){printf("%d ", arr[yy]);}
}
void xixi()
{int arr[] = { 9, 8, 6, 7, 2, 3, 6, 1, 0, 12 };int sz = sizeof(arr) / sizeof(arr[0]);my_qsort(arr, sz, sizeof(arr[0]), daxiao);dayin(arr, sz);
}
int main()
{xixi();return 0;
}
上面是my_qsort的全部代码,那么我们接下来分段来解释每段代码的作用。首先主函数和创建数组传递参数这个大家知道吧。我们先解读一下my_qsort中的数据含义。arr肯定是数组名,sz是数组元素个数,sizeof(arr[0])是数组元素大小,daxiao判断升降序。
我们也都知道qsort一些关键数据需要用void*来接收(因为void*的特性)。但大家应该也注意到了在my_qsort最后接收数据的时候,我们使用的是int (*pf)( void *p1,void *p2)。那这个是什么嘞。首先大家要知道这个叫函数指针,因为我们在这个代码中包含了另外一个需要使用的代码,使用需要将确定其使用的指针名,数据,返回值(当然我们后面会详细的讲解一下这个是什么东西,大家现在可以先记住这个是什么东西,长什么样子)。然后进入代码里面还是经典的双循环。然后判断,那么就是我刚刚说的函数指针判断大小了
那么我们也只是说了,这个代码只是包含的另外一个,那么这个代码是不完全的,所以我们接着就要去晚上这个判断大小的代码。因为函数指针int (*pf)( void *p1,void *p2)中*pf就是这个指针的名字。那么我们接下来( void *p1,void *p2)就是传递的参数,所以大家可以将pf((char*)arr + y *ha, (char*)arr + (y + 1)*ha)理解为子程序名(参数,参数)。那么这里了解了,我们就来完整这个代码:
首先为什么是daxiao这个数组名,是因为在创建数组my_qsort中我们就将判断大小的囊位置确定了名字就叫daxiao所以以防程序错误,我们名字需要一样。然后也是老样子,相减返回,来确定大小。然后回到my_qsort中判断是想要升序还是降序所以交换。
这里大家需要注意的是,为什么我们在接收数据的时候强转char类型。因为char类型只有2个字节。大家应该注意到了吧,我们传递过来的数据中除了交换的两个元素外还有一个字节大小。我们把这两个结合,大家是否想到了。2个字节在c语言数据类型中是最小的,并且使用的类型大小都是2的倍数,那么我们只需要多循环几次,岂不是就可以用2个字节依次交换就交换结束了。然后就是最后的步骤打印了。当然我们在开头就写了打印的代码了。这里就不多赘述了,我们直接看结果。
所以自实现my_qsort只需要以下加点:
1:主函数,创建数组
2:my_qsort接收数据,双循环,判断大小(是否升降序)
3:函数指针实现判断大小
4:交换数据
5:写交换结果
这些就是my_qsort的大概步骤了。当然还有步骤需要大家了解,大家可以多看一下来增加对这个代码的熟悉度。好了如果还有很多不对的地方,希望大家可以在下方评论区写出来。
相关文章:

C语言----冒泡排序进阶
冒泡排序大家应该到写过吧。但大家可能知道到的冒泡排序有两种方法。而我呢,最近学习到了另外一种方法,现在知道三种方法了。所以想与大家分享一下。但是缺点是第三种是第二种的自实现版。第一种就是我们平常写的普通冒泡排序。第二种就是qsort。第三种就…...

【机器学习】实验5,AAAI 会议论文聚类分析
本次实验以AAAI 2014会议论文数据为基础,要求实现或调用无监督聚类算法,了解聚类方法。 任务介绍 每年国际上召开的大大小小学术会议不计其数,发表了非常多的论文。在计算机领域的一些大型学术会议上,一次就可以发表涉及各个方向…...

安卓虚拟机ART和Dalvik
目录 一、JVM和Dalvik1.1 基于栈的虚拟机字节码指令执行过程 1.2 基于寄存器的虚拟机 二、ART与Dalvikdex2aotAndroid N的运作方式 三、总结 一、JVM和Dalvik Android应用程序运行在Dalvik/ART虚拟机,并且每一个应用程序对应有一个单独的Dalvik虚拟机实例。 Dalvik…...

OPENWRT本地局域网模拟域名多IP
本地配置MINIO服务时,会遇到域名多IP的需求。当某一个节点失效时,可以通过域名访问平滑过渡到其它的节点继续服务。 【MINIO搭建过程略】 搭建完毕后,有4个节点,对应的docker搭建命令: docker run --nethost --rest…...

今日学习总结2024.3.2
最近的学习状态比较好,感觉非常享受知识进入脑子的过程,有点上头。 实验室一个星期唯一一天的假期周六,也就是今天,也完全不想放假出去玩啊,在实验室泡了一天。 很后悔之前胆小,没有提前投简历找实习&…...

Java虚拟机(JVM)从入门到实战【上】
Java虚拟机(JVM)从入门到实战【上】,涵盖类加载,双亲委派机制,垃圾回收器及算法等知识点,全系列6万字。 一、基础篇 P1 Java虚拟机导学课程 P2 初识JVM 什么是JVM Java Virtual Machine 是Java虚拟机。…...

SaaS 电商设计 (九) 动态化且易扩展的实现购物车底部弹层(附:一套普适的线上功能切量的发布方案)
目录 一.背景1.1 业务背景1.2 技术负债 二.技术目标三.方案设计3.1 解决移动端频繁发版3.1.1 场景分析3.1.2 技术方案 3.2 减少后端坏味道代码&无法灵活扩展问题3.2.1 通过抽象接口完成各自单独楼层渲染逻辑3.2.2 通过配置能力做到部分字段可配 四.升级上线(普适于高并发大…...

数据结构——lesson5栈和队列详解
hellohello~这里是土土数据结构学习笔记🥳🥳 💥个人主页:大耳朵土土垚的博客 💥 所属专栏:数据结构学习笔记 💥对于顺序表链表有疑问的都可以在上面数据结构的专栏进行学习哦~感谢大家的观看与…...
使用rsync同步服务器和客户端的文件夹
使用rsync同步服务器和客户端的文件夹 实现目的实验准备实验操作步骤服务器操作关闭防火墙和SELINUX安装rsync修改服务器配置文件/etc/rsync.conf创建服务器备份文件的目录创建rsync系统运行的用户修改备份文件的所有者和所属组创建rsync.passwd启动rsync服务并进行验证 客户端…...

计算机网络|Socket
文章目录 Socket并发socket Socket Socket是一种工作在TCP/IP协议栈上的API。 端口用于区分不同应用,IP地址用于区分不同主机。 以下是某一个服务器的socket代码。 其中with是python中的一个语法糖,代表当代码块离开with时,自动对s进行销毁…...
Python 使用 MyHDL库 实现FPGA板卡仿真验证
要使用 Python 结合 MyHDL 库实现 FPGA 板卡的仿真验证,您可以利用 MyHDL 提供的硬件描述语言和仿真功能来进行 FPGA 设计的验证。下面我将为您介绍一个简单的示例,演示如何使用 MyHDL 库进行 FPGA 设计的仿真验证。 步骤概述 编写 MyHDL 硬件描述&…...
解决SpringBoot集成WebSocket打包失败问题
前言 这几天在一个SpringBoot项目中使用WebSocket来用作客服聊天以及上传文件功能,项目在写的时候,以及在idea中跑的时候都非常完美,结果一打成jar包是,报错.在网上查了报错原因,原来是自己导入的WebSocket的jar与SpringBoot内置tomcat中的WebSocket的jar冲突,需要在打包时把S…...
i-vista五星测试标准
智能行车板块以八类场景评测汽车的 单车道纵向控制能力、 单车道横向控制能力、 单车道纵横向组合控制能力及换道辅助能力, 8类场景包括目标车静止、目标车低速、目标车减速、前车切入(新增场景)、直道居中行驶、直道驶入弯道、盲区无车、盲…...

初识Maven
介绍: web后端开发技术ApacheMaven是一个项目管理和构建工具,它基于项目对象模型(POM)的概念,通过一小段描述信息来管理项目的构建。安装:http://maven.apache.org/ Apache软件基金会,成立于19…...
16 Educational Codeforces Round 142 (Rated for Div. 2)C. Min Max Sort(递归、思维、dp)
C. Min Max Sort 很不错的一道题目,不过脑电波和出题人每对上, q w q 。 qwq。 qwq。 正难则反。 我们考虑最后一步是怎么操作的。 最后一步一定是对 1 1 1和 n n n进行操作 那么上一步呢? 上一步应该是对 2 2 2和 n − 1 n-1 n−1 以此类推…...

Mongodb安装配置
Mongodb安装配置 一、MongoDB简介二、Windows下MongoDB安装2.1.MongoDB下载2.2.安装MongoDB【解压版】2.2.1.解压2.2.2.创建和 bin 目录同级 data\db 目录来存储 MongoDB 产生的数据2.2.3.进入 bin 目录,cmd命令行窗口,使用命令的指定存储数据文件的形式…...
Linux常用操作命令大全
Linux常用操作命令大全 Linux,作为一款开源的操作系统,深受全世界开发者和系统管理员的喜爱。在Linux环境下,用户通过命令行界面可以执行各种操作,从而实现对系统的全面控制。本文将详细介绍Linux中常用的操作命令,帮助读者更好地理解和运用这些命令。 一、文件操作命令…...

CVPR2023 | 提升图像去噪网络的泛化性,港科大上海AILab提出 MaskedDenoising,已开源!
作者 | 顾津锦 首发 | AIWalker 链接 | https://mp.weixin.qq.com/s/o4D4mNM3jL6sYuhUC6VgoQ 当前深度去噪网络存在泛化能力差的情况,例如,当训练集噪声类型和测试集噪声类型不一致时,模型的性能会大打折扣。作者认为其原因在于网络倾向于过度…...
[python] dict类型变量写在文件中
在Python中,如果你想要将一个字典变量以具有可读性的格式写入文件,并且指定缩进为2个空格,你可以使用json模块来实现。json模块提供了一种很方便的方法来进行序列化和反序列化Python对象。下面是一个具体的示例: 字典变量以具有可…...

设计循环队列
文章目录 一、循环队列的构建二、判断是否为空三、判断队列是否满了四、队列插入五、队列的删除六、队列取头尾 设计循环队列 下面是队列提供的接口函数 typedef struct {int* a;int k;int front;int rear; } MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k) {…...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...

Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...

中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...