使用冒泡排序模拟实现qsort函数
1.冒泡排序
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>int main()
{int arr[] = { 0,2,5,3,4,8,9,7,6,1 };int sz = sizeof(arr) / sizeof(arr[0]);//冒泡排序一共排序 sz-1 趟for (int i = 0; i < sz - 1; ++i){//标志位,如果有序,直接退出int flag = 0;//第一趟比较sz-1次,//以后每趟比较次数-1for (int j = 0; j < sz - 1 - i; ++j){if (arr[j] > arr[j + 1]){flag = 1;int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}if (!flag)break;}for (int i = 0; i < sz; ++i)printf("%d ", arr[i]);return 0;
}
2.模拟实现
2.1认清障碍
qsort函数可以实现任意数据的排序
但此时的冒泡排序不行,阻碍点:
(1)
冒泡排序中 if 条件判断中的 >
注定了该算法不能实现其他数据的比较
想到:
模仿qsort函数,在冒泡排序内部
调用相关函数实现数据比较
然后根据调用函数的返回值进行后续操作
(2)
上面的交换方式也受到了限制
想到:
需要实现一个
可以实现数据交换的函数
2.2克服障碍

2.2.1依葫芦画瓢
那就依葫芦画瓢,写下声明
void Bubble_sort(void*base,size_t num,size_t width,int(*cmp)(const void*p1,const void*p2));此时:
从左往右,要传入的
第一个参数是 待排序数组的第一个元素的地址
第二个参数是 元素个数
第三个参数是 每个元素的大小,单位是字节
第四个参数是 一个函数指针
Bubble_sort函数通过这个函数指针调用相关的函数
被调用的函数就是用来实现任意数据的比较方式的
被调用的函数:
返回值为int,形参为(const void*p1,const void*p2)
(1)
p1指向一个数组元素
p2指向的是p1指向的元素之后的第一个元素
(2)函数内部的要求:
(2.1)void*不能直接解引用或+-整数操作
所以需要根据需求进行相应的显式类型转换
(2.2)显示类型转换后,
当p1指向的内容大于p2时,函数返回 大于0的值
当p1指向的内容小于p2时,函数返回 大于0的值
当p1指向的内容等于p2时,函数返回 0
2.2.2逐步实现
void Bubble_sort(void*base,size_t num,size_t width,int(*cmp)(const void*p1,const void*p2))
{for (int i = 0; i < num - 1; ++i){int flag = 0;for (int j = 0; j < num - 1 - i; ++j){if(){}}if (!flag)break;}
}
冒牌排序外壳:
趟数、比较次数不用改变
2.2.2.1条件判断
if 语句中,根据函数调用返回值进行判断
假设,当当p1指向的内容大于p2时,才进行数据的交换
那么,代码如下:
void Bubble_sort(void*base,size_t num,size_t width,int(*cmp)(const void*p1,const void*p2)) {for (int i = 0; i < num - 1; ++i){int flag = 0;for (int j = 0; j < num - 1 - i; ++j){if(cmp((char*)base+j*width,(char*)base+(j+1)*width)>0){flag = 1;..}}if (!flag)break;} }
详细解释:
(1)绿色方框框起来的意思是
(1.1)这是两个实参
(1.2)指针指向一种数据时,
总是指向该数据所占空间地址最小的那个字节
(1.3)base接收了数组首元素的地址,但是
我并不知道这是整型、浮点型、字符型的数组
所以我将它强制转换为(char*)类型的指针
这样,无论如何
(char*)base 都指向了数组首元素的第一个字节
(1.4)函数传参传进了width,
注意到:
如果是一个int型的数组
(char*)base 指向了数组首元素的第一个字节
(char*)base+width指向了数组第二个元素的第一个字节
(char*)base+2*width指向了数组第三个元素的第一个字节
如果是一个char型的数组
(char*)base 指向了数组首元素
(char*)base+width指向了数组第二个元素
(char*)base+2*width指向了数组第三个元素
所以:
实参就是
((char*)base+j*width,(char*)base+(j+1)*width)
(2)橙色方框框起来的意思是
调用cmp函数
(3)红色方框框起来的意思是
当cmp函数返回值>0时,才进行后续的操作
2.2.2.2交换方式
避免代码冗余,创建一个Swap函数进行数据的交换
void Bubble_sort(void*base,size_t num,size_t width,int(*cmp)(const void*p1,const void*p2))
{for (int i = 0; i < num - 1; ++i){int flag = 0;for (int j = 0; j < num - 1 - i; ++j){if(cmp((char*)base+j*width,(char*)base+(j+1)*width)>0){flag = 1;Swap((char*)base+j*width,(char*)base+(j+1)*width, width);}}if (!flag)break;}
}
(1)我们并不知道元素的类型
但是因为我们知道元素的大小
所以我们可以逐字节地交换两个元素
(2)此时,传入的参数应该是
两个元素的第一个字节、元素的大小
Swap((char*)base+j*width,(char*)base+(j+1)*width, width);
内部实现:
void Swap(char* p1, char* p2, size_t width) {for (int i = 0; i < width; ++i){char temp = *p1;*p1 = *p2;*p2 = temp;p1++;p2++;} }(1)width有多大,就交换几次
每次交换后,指针偏移
2.3测试
使用Bubble_sort函数与使用qsort函数一样
需要自己编写一个实现数据比较地函数
这是整型数据的比较
这是字符间的排序 :
注意,元素个数用strlen求!
这是字符串间的排序:
相关文章:
使用冒泡排序模拟实现qsort函数
1.冒泡排序 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h>int main() {int arr[] { 0,2,5,3,4,8,9,7,6,1 };int sz sizeof(arr) / sizeof(arr[0]);//冒泡排序一共排序 sz-1 趟for (int i 0; i < sz - 1; i){//标志位,如果有序,直接…...
AI大模型开发原理篇-4:神经概率语言模型NPLM
神经概率语言模型(NPLM)概述 神经概率语言模型(Neural Probabilistic Language Model, NPLM) 是一种基于神经网络的语言建模方法,它将传统的语言模型和神经网络结合在一起,能够更好地捕捉语言中的复杂规律…...
Eigen::Tensor使用帮助
0 引言 用python实现了某些算法之后,想转成C来获取更高的性能。但是python数组的操作太灵活了,尤其是3维、4维、5维等高维数组,以及它们的广播、数组坐标、切片等机制。还有numpy的pad、where等操作更是给C转换带来了更多的麻烦。 查阅了相…...
git基础使用--3---git安装和基本使用
文章目录 git基础使用--3--git-安装和基本使用1. git工具安装1.1 git1.2 TortoiseGit1.3 远程仓2. git本地仓库版本管理2.1 git常用命令2.2 git基本操作2.2.1 设置用户名和邮箱 2.2 git基本操作2.2.1 初始化本地仓 git init2.2.2 查看本地库状态 git status2.2.3 添加暂缓区2.2…...
html的字符实体和颜色表示
在HTML中,颜色可以通过以下几种方式表示,以下是具体的示例: 1. 十六进制颜色代码 十六进制颜色代码以#开头,后面跟随6个字符,每两个字符分别表示红色、绿色和蓝色的强度。例如: • #FF0000:纯红…...
OpenAI发布o3-mini:免费推理模型,DeepSeek引发的反思
引言 在人工智能领域,OpenAI再次引领潮流,推出了全新的推理模型系列——o3-mini。这一系列包括low、medium和high三个版本,旨在进一步推动低成本推理的发展。与此同时,OpenAI的CEO奥特曼也在Reddit的“有问必答”活动中罕见地公开…...
Zemax 中带有体素探测器的激光谐振腔
激光谐振腔是激光系统的基本组成部分,在光的放大和相干激光辐射的产生中起着至关重要的作用。 激光腔由两个放置在光学谐振器两端的镜子组成。一个镜子反射率高(后镜),而另一个镜子部分透明(输出耦合器)。…...
大模型训练(5):Zero Redundancy Optimizer(ZeRO零冗余优化器)
0 英文缩写 Large Language Model(LLM)大型语言模型Data Parallelism(DP)数据并行Distributed Data Parallelism(DDP)分布式数据并行Zero Redundancy Optimizer(ZeRO)零冗余优化器 …...
C# 实现 “Hello World” 教程
.NET学习资料 .NET学习资料 .NET学习资料 C# 作为一种广泛应用于.NET 开发的编程语言,以其简洁、高效和类型安全等特性,深受开发者喜爱。在踏入 C# 编程领域时,编写经典的 “Hello World” 程序是重要的起点,它能帮助我们快速熟…...
LabVIEW无线齿轮监测系统
本案例介绍了基于LabVIEW的无线齿轮监测系统设计。该系统利用LabVIEW编程语言和改进的天牛须算法优化支持向量机,实现了无线齿轮故障监测。通过LabVIEW软件和相关硬件,可以实现对齿轮箱振动信号的采集、传输和故障识别,集远程采集、数据库存储…...
IM 即时通讯系统-01-概览
前言 有时候希望有一个 IM 工具,比如日常聊天,或者接受报警信息。 其实主要是工作使用,如果是接收报警等场景,其实DD这种比较符合场景。 那么有没有必要再创造一个DD呢? 答案是如果处于个人的私有化使用࿰…...
【人工智能】 在本地运行 DeepSeek 模型:Ollama 安装指南
持续更新。。。。。。。。。。。。。。。 【人工智能】 在本地运行 DeepSeek 模型:Ollama 安装指南 安装 Ollama安装 DeepSeek 模型选择版本 ,版本越高,参数越多 性能越好使用 DeepSeek 模型 安装 Ollama 访问 Ollama 官网: 前往 https://oll…...
【Linux系统】信号:信号保存 / 信号处理、内核态 / 用户态、操作系统运行原理(中断)
理解Linux系统内进程信号的整个流程可分为: 信号产生 信号保存 信号处理 上篇文章重点讲解了 信号的产生,本文会讲解信号的保存和信号处理相关的概念和操作: 两种信号默认处理 1、信号处理之忽略 ::signal(2, SIG_IGN); // ignore: 忽略#…...
探索 Copilot:开启智能助手新时代
探索 Copilot:开启智能助手新时代 在当今数字化飞速发展的时代,人工智能(AI)正以前所未有的速度改变着我们的工作和生活方式。而 Copilot 作为一款强大的 AI 助手,凭借其多样的功能和高效的应用,正在成为众…...
解锁豆瓣高清海报(二) 使用 OpenCV 拼接和压缩
解锁豆瓣高清海报(二): 使用 OpenCV 拼接和压缩 脚本地址: 项目地址: Gazer PixelWeaver.py pixel_squeezer_cv2.py 前瞻 继上一篇“解锁豆瓣高清海报(一) 深度爬虫与requests进阶之路”成功爬取豆瓣电影海报之后,本文将介绍如何使用 OpenCV 对这些海报进行智…...
我用Ai学Android Jetpack Compose之Card
这篇学习一下Card。回答来自 通义千问。 我想学习Card,麻烦你介绍一下 当然可以!在 Jetpack Compose 中,Card 是一个非常常用的组件,用于创建带有阴影和圆角的卡片式布局。它可以帮助你轻松实现美观且一致的 UI 设计,…...
NLP深度学习 DAY4:Word2Vec详解:两种模式(CBOW与Skip-gram)
用稀疏向量表示文本,即所谓的词袋模型在 NLP 有着悠久的历史。正如上文中介绍的,早在 2001年就开始使用密集向量表示词或词嵌入。Mikolov等人在2013年提出的创新技术是通过去除隐藏层,逼近目标,进而使这些单词嵌入的训练更加高效。…...
论文阅读(十):用可分解图模型模拟连锁不平衡
1.论文链接:Modeling Linkage Disequilibrium with Decomposable Graphical Models 摘要: 本章介绍了使用可分解的图形模型(DGMs)表示遗传数据,或连锁不平衡(LD),各种下游应用程序之…...
Python中容器类型的数据(上)
若我们想将多个数据打包并且统一管理,应该怎么办? Python内置的数据类型如序列(列表、元组等)、集合和字典等可以容纳多项数据,我们称它们为容器类型的数据。 序列 序列 (sequence) 是一种可迭代的、元素有序的容器类型的数据。 序列包括列表 (list)…...
PySPARK带多组参数和标签的SparkSQL批量数据导出到S3的程序
设计一个基于多个带标签SparkSQL模板作为配置文件和多组参数的PySPARK代码程序,实现根据不同的输入参数自动批量地将数据导出为Parquet、CSV和Excel文件到S3上,标签和多个参数(以“_”分割)为组成导出数据文件名,文件已…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...
快刀集(1): 一刀斩断视频片头广告
一刀流:用一个简单脚本,秒杀视频片头广告,还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农,平时写代码之余看看电影、补补片,是再正常不过的事。 电影嘛,要沉浸,…...
在树莓派上添加音频输入设备的几种方法
在树莓派上添加音频输入设备可以通过以下步骤完成,具体方法取决于设备类型(如USB麦克风、3.5mm接口麦克风或HDMI音频输入)。以下是详细指南: 1. 连接音频输入设备 USB麦克风/声卡:直接插入树莓派的USB接口。3.5mm麦克…...








