好用的库函数,qsort函数大详解(干货满满!)(进阶)

news2024/11/24 13:23:19

前言:

  小编在上一篇文章说了这一篇将要写qsort函数的模拟实现,那么废话不多说,现在开始进入今天的代码之旅喽!


目录:

1.qsort函数的模拟实现的逻辑和思路

2.qsort函数模拟实现的代码实现

3.代码展示


1.qsort函数的模拟实现的逻辑和思路

  读者朋友们是否还记得小编之前说过的一个排序的算法:冒泡排序,今天我们就是用它来模拟实现qsort函数的,如果有读者朋友略微忘记的话,小编先从这里呈现冒泡排序代码的实现来让读者朋友们回忆部分内容:

void my_paopao(int arr[10], int sz)
{
	int i = 0;
	int flag = 1;
	for (i = 0; i < sz - 1; i++)
	{
		int j = 0;
		for (j = 0; j < sz - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmo = 0;
				tmo = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmo;
				flag = 0;
			}
			if (flag == 1)
				break;
		}
	}
}
int main()
{
	int arr[10] = { 0 };
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		scanf("%d", arr + i);
	}
	int sz = sizeof(arr) / sizeof(arr[0]);
	my_paopao(arr, sz);
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

  上面就是冒泡排序代码的实现,如果稍微有点记不清的读者朋友可以看上述代码回忆一下,或者浏览:C语言重要算法之一——冒牌排序详解(干货满满,欢迎各位朋友的观看)-CSDN博客 ,这个是我以前写过的博客,大家可以看这个回顾,回归正题,我们知道,冒泡排序只能排序整型,而qsort函数可以排序任意类型的数组,我们可以以冒泡排序为整体的框架,从而可以模拟qsort函数。

  首先,我们先来回顾一下,qsort函数内部的内容,通过上次小编介绍的网站可以清晰的看到: 

   我们可以先仿照这个来先写一个类似的函数,因为这个是我们自己模拟的,所以可以自己命名,我们对函数描述完以后,就要写函数的主题了,小编前面说过,我们可以保留冒泡排序的框架,所以我们先把代码拿出来来进行思考:

void my_qsortvoid *base,size_t count,size_t width,int (*cop)(const void* p1,const void* p2) )   //这里完全对照qsort函数本身括号内部的内容
{
	int i = 0;
	int flag = 1;
	for (i = 0; i < sz - 1; i++)
	{
		int j = 0;
		for (j = 0; j < sz - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmo = 0;
				tmo = arr[j];
				arr[j] = arr[j + 1];   //当然我们不能这么比较,因为我们有可能设计到字符的比较,对于改进我们在下面叙说,毕竟咱不能一口气吃个小编
				arr[j + 1] = tmo;
				flag = 0;
			}
			if (flag == 1)
				break;
		}
	}
}

  正如我在上面所说,我们可以把循环给保存好,然后对于内容进行修改,不知道读者朋友们是否还记得小编之前说过qsort是怎么判定可以交换的,如果忘记了请看下图 :

   当返回值大于0的时候将会让两个数进行交换,小于0或者等于0的时候是不发生交换的,那么这个时候,我们就可以我们写的最后一个函数(括号最后一个)指针来进行比较操作,通过此函数的返回值来比较是否大于0,如果大于0再进行交换操作。

  交换操作可以通过我们再写一个交换函数来进行数值的交换,我们在交换的时候,要考虑到我们传参的时候不一定传的就是整型,我们上面式子的交换是只是针对整形的,对于字符型的,小编认为,我们可以通过一个一个字节的来进行交换,这样的话,我们既可以针对字符型,也可以针对整型了,现在我们已经有了这个函数的大致思路了,下面就我们就来进行函数的写正式描写喽!

 

2.qsort函数模拟实现的代码实现

  我们刚开始就要先写一下函数名,通过我们对于qsort函数的了解,下面是代码的实现: 

int arr[10] = { 3,4,5,6,7,8,9,10,1,2 };
int sz = sizeof(arr) / sizeof(arr[0]);
my_qsort(arr, sz, sizeof(arr[0]), com_per);  //这里放函数名就好

  之后,我们就要进行比较环节了,循环方面小编就不写了(待会会把完整的代码发出来,大家不要着急),我们首先要靠比较函数来比较大小,对于这方面的实现,我们其实可以完全仿照我们之前运用比较函数的样子,首先我们要先写一个if语句来判定它与0之间的大小关系,下面是代码呈现:

	if (cop((char*)base + j * width, (char*)base + (j+1) * width) > 0)
	{
		comper((char*)base + j * width, (char*)base + (j + 1) * width, width);   //这是交换的(适用于任何的数)
	}

  对于函数如何进行比较,小编放在了下图,完全可以仿照我们使用它的时候的比较进行书写(我们这里就以char类型的数据举例): 

 int com_per(const void* p1, const void* p2)
{
	return ((*(char*)p1) - (*(char*)p2));   //对于字符串的比较才用strcmp
}

  所以说,比较函数我们就原封不动的写就好(此时也是展现了为什么这么比较就可以实现两个数的交换),之后就到了我们这个代码的重头戏,对于我们如何进行两个数的交换,小编在思路部分就说了,我们可以实现一个字节一个字节的交换从而完成所有的交换,所以我们可以直接用char*指针对于我们比较两个数进行接受,然后我们可以写一个循环,通过这个循环来实现每个字节的交换,对于次数的限制,我们就以我们比较数的大小作为最大次数,从而实现字节的交换,我光说可能大家都很疑惑,下面是完整的代码展示:

void comper(char* a1, char* a2,int width)
{
	int i = 0;
	char a = 0;
	for (i = 0; i < width; i++)
	{
		a = *a1;
		*a1 = *a2;
		*a2 = a;
		a1++;
		a2++;
	}
}

  上面便是对于这个交换函数进行的描写,与小编说的一样,此时我们通过循环便可以实现每个数的交换,可能有些读者很疑惑,认为整型是怎么实现交换的,为此小编通过图文的形式进行解释: 

   虽然小编画的有点抽象,但是是这么个道理,这里确实实现了两个数的交换,那么我们通过每次循环,来对于数进行交换了,最终会实现此代码的实现,下面来展示一下这个代码最后的运行图:

   可以很清楚的看已经完成了升序环节,证明此函数模拟成功了,可能现在还有很多读者朋友不知道如何完整的实现这个功能,不要急,小编这就给大家展示源代码!

 

3.代码展示

  小编这里就拿整型和字符型来进行展示了

整型的主函数:

	int arr[10] = { 3,4,5,6,7,8,9,10,1,2 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	my_paopao(arr, sz, sizeof(arr[0]), com_per);  //这里放函数名就好
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}

模拟函数(这里通用的,所以下面也不展示了):

void my_paopao(void *base,size_t count,size_t width,int (*cop)(const void* p1,const void* p2))   //这里是模仿的qsort里面的内容来写的
{    //上面也用到了回调函数的思想
	int i = 0;
	for (i = 0; i < count - 1; i++)            //这里采用的模板是按照冒泡排序的思想来写的,外在并没被改变,但是内在却和冒泡排序是截然不同的
	{
		int j = 0;
		for (j = 0; j < count - i - 1; j++)
		{
			if (cop((char*)base + j * width, (char*)base + (j+1) * width) > 0)
			{
				comper((char*)base + j * width, (char*)base + (j + 1) * width, width);   //这是交换的(适用于任何的数)
			}
		}
	}
}

 比较函数:

int com_per(const void* p1, const void* p2)
{
	return (*(int*)p1 - *(int*)p2);
}

交换函数(这个是通用的,小编下面就不写了):

void comper(char* a1, char* a2,int width)
{
	int i = 0;
	char a = 0;
	for (i = 0; i < width; i++)
	{
		a = *a1;
		*a1 = *a2;
		*a2 = a;
		a1++;
		a2++;
	}
}

字符型主函数:

	char arr[10] = { 'a','c','d','b','e','h','q','u','x','z' };
	int sz = sizeof(arr) / sizeof(arr[0]);
	my_paopao(arr, sz, sizeof(arr[0]), jisuan);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%c ", arr[i]);
	}

比较函数:

 int jisuan(const void* p1, const void* p2)
{
	return ((*(char*)p1) - (*(char*)p2));   //对于字符串的比较才用strcmp
}

总结;

  小编先声明一下,小编这里是用冒泡排序的方式来模拟实现这个函数的,但不一定代表着只有冒泡排序才可以模拟实现这个函数,对于这个函数的具体实现可能也就只有制作这个函数的人知道了,读者朋友们学会其中的思想就好了,在这里,小编也是连着更了七天的博客了,在这期间我也发现了我忘记了很多知识,果然还是那句话:温故而知新可以为师矣 !大家平常一定要多复习自己学过的知识,避免忘记过多,明天可能会停更一天,小编歇一天,如果文章有错误,恳请大家指出,小编虚心求教,我们下一篇博客见喽!

 

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

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

相关文章

YOLOv9独家提点|加入MobileViT 、SK 、Double Attention Networks、CoTAttention等几十种注意力机制(五)

本文介绍了YOLOv9模型的改进,包括加入多种注意力机制,如SE、CBAM、ECA和SimAM。此外,还探讨了MobileViT轻量级视觉Transformer在移动设备上的应用,以及SelectiveKernelNetworks和A2-Nets的双注意力结构。最后,CoTAttention网络在视觉问答任务中的改进展示了跨模态注意力交…

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 6月17日,星期一

每天一分钟&#xff0c;知晓天下事&#xff01; 2024年6月17日 星期一 农历五月十二 1、 今年首个红色山洪灾害预警&#xff1a;17日&#xff0c;浙江西南部、福建北部局地发生山洪灾害可能性很大。 2、 国家医疗保障局重构产科服务价格项目&#xff0c;“分娩镇痛”亲情陪产…

AI大模型在运动项目的深度融合和在穿戴设备的实践及未来运动健康技术发展

文章目录 1. 技术架构2. 模型选择2.1 LSTM&#xff08;长短期记忆网络&#xff09;2.2 CNN&#xff08;卷积神经网络&#xff09;2.3 Transformer 3. 数据处理数据预处理 4. 实时性要求4.1 边缘计算4.2 模型优化 5. 数据隐私与安全6. 深入分析AI大模型在穿戴设备的应用和未来发…

Yum安装LAMP

查看当前80端口是否被占用 ss -tulanp | grep 80查询httpd是否在yum源中 yum info httpd安装httpd yum -y install httpd启动httpd服务&#xff0c;设置开机自启 systemctl enable httpd --now systemctl start httpd查看当前进程 ps aux | grep httpd查看当前IP&#xff…

Google谈出海:品牌「性价比」转向「心价比」

Google Marketing Live中国站活动现场 越来越多的中国全球化品牌基于对全球消费和海外地区的深刻洞察&#xff0c;不断提升产品研发和迭代能力&#xff0c;在海外消费者心中塑造「中国质造」和「中国智造」的新形象。2023年6月15日&#xff0c;凯度与Google合作发布《2023 凯…

AI数据分析:根据Excel表格数据进行时间序列分析

ChatGPT中输入提示词&#xff1a; 你是一个Python编程专家&#xff0c;要完成一个Python脚本编写的任务&#xff0c;具体步骤如下&#xff1a; 读取Excel表格&#xff1a;"F:\AI自媒体内容\AI行业数据分析\toolify月榜\toolify2023年-2024年月排行榜汇总数据.xlsx"…

vite-plugin-pwa 离线安装Vite应用

渐进式Web应用&#xff08;PWA&#xff09;通过结合 Web 和移动应用的特点&#xff0c;为用户带来更加流畅和快速的体验。且PWA支持离线访问能力&#xff08;访问静态资源本地缓存&#xff09;&#xff0c;极大提高了用户交互的流畅性&#xff0c;降低非必要的网络依赖。尤其适…

基于 U-Net 的图像分割

点击下方卡片&#xff0c;关注“小白玩转Python”公众号 图像分割是一种将图像划分为不同区域或对象的过程。它通常在像素级别进行&#xff0c;通过将图像中具有相似特征的区域分组或定义对象的边界来完成。这是一种识别和解析图像中不同对象或特征的方法。 假设一位医学专业人…

气象数据NC、grb2解析成矢量json、CMIS、MICPS及图片应用到webgis

一、基础概念 气象数据通常以多种格式存储和交换&#xff0c;以适应不同的应用需求和处理工具。以下是一些常见的气象数据格式及其转换方法的概述&#xff1a; 常见气象数据格式 1. NetCDF&#xff08;Network Common Data Form&#xff09;&#xff1a;一种自描述、自包含的…

SD卡、MicroSD卡与SD NAND的全面对比分析

在当今多样化的存储设备市场中&#xff0c;SD卡、MicroSD卡和SD NAND因其不同的特性和应用场景而广受欢迎。这三种存储解决方案各有千秋&#xff0c;为消费者提供了丰富的选择。以下是MK米客方德SD卡、MicroSD卡和SD NAND全面的对比分析&#xff1a;

springboot“漫画之家”系统 LW+PPT+源码

3 系统分析 链接&#xff1a;https://pan.baidu.com/s/1ihILTui-XEFdC15mcOB0vA?pwdewry 提取码&#xff1a;ewry 3.1系统可行性分析 3.1.1经济可行性 由于本系统是作为毕业设计系统&#xff0c;且系统本身存在一些技术层面的缺陷&#xff0c;并不能直接用于商业用途&#xf…

英伟达发布开源模型Nemotron-4 340B

&#x1f680; 英伟达发布开源模型Nemotron-4 340B 摘要&#xff1a;英伟达最新发布的开源模型Nemotron-4 340B&#xff0c;可能彻底改变大语言模型&#xff08;LLM&#xff09;训练方式。该模型支持多种自然语言和编程语言&#xff0c;使用9万亿个token训练&#xff0c;高达9…

python数据分析-心脏瓣膜手术风险分析与预测

一、研究背景和意义 人的心脏有四个瓣膜&#xff0c;主动脉银、二尖、肺动脉和三尖源 不管是那一个膜发生了病变&#xff0c;都会导致心脏内的血流受到影响&#xff0c;这就是通常所说的心脏期膜病&#xff0c;很多是需要通过手术的方式进行改善的。随着人口老龄化的加剧,&…

Aeron:Multi-Destination-Cast

Multi-Destination-Cast&#xff08;MDC&#xff09;是一种功能&#xff0c;允许 Aeron 从单个 Publication 同时向多个目的地传送数据。Multiple-Destination-Cast是 Aeron 的一项高级功能&#xff0c;本指南将介绍如何开发一个简单示例的基本知识。 一、MDC Publications 注&…

机器学习中的监督学习介绍

In this post well go into the concept of supervised learning, the requirements for machines to learn, and the process of learning and enhancing prediction accuracy. 在这篇文章中&#xff0c;我们将深入探讨监督学习的概念、机器学习的要求以及学习和提高预测准确…

Proxmox VE (PVE) 教学 (3) | 在 Proxmox VE 中安装与配置 OpenWrt

大家好,很长时间没有更新这个系列了。最近正在开发新项目,刚刚想起来我是不是还有一个什么专栏没更新。 本期的网络配置背景同于前两期的描述( 详见https://www.hestudio.net/category/proxmox-ve/ ),这一期只是对网络配置的扩展,也就是安装软路由,实现网络配置的更多功…

计算机网络:1概述

概述 因特网 网络、互连网&#xff08;互联网&#xff09;与因特网的区别与关系 若干节点和链路互连形成网络&#xff0c;若干网络通过路由器互连形成互连网&#xff0c;世界上最大的互连网是互联网&#xff08;因特网Internet&#xff09;。 因特网发展的三个阶段 因特网…

【挑战100天首通《谷粒商城》】-【第一天】【10 番外篇】 解决docker 仓库无法访问 + MobaXterm连接VirtualBox虚拟机

文章目录 课程介绍 1、解决docker 仓库无法访问 2、 MobaXterm连接VirtualBox虚拟机 Stage 1&#xff1a;下载MobaXterm选择适合你的版本 Stage 2&#xff1a;vagrant ssh 连接&#xff0c;开启ssh访问 Stage 2-1&#xff1a;su获取root账号权限,输入密码&#xff08;默认vagra…

C语言笔记第15篇:文件操作

1、为什么使用文件&#xff1f; 如果没有文件&#xff0c;我们写的程序的数据是存储在电脑的内存中&#xff0c;如果程序退出&#xff0c;内存回收&#xff0c;数据就丢失了&#xff0c;等再次运行程序&#xff0c;是看不到上次程序的数据的&#xff0c;如果要将数据进行持久化…

Java 集合框架:LinkedList 的介绍、使用、原理与源码解析

大家好&#xff0c;我是栗筝i&#xff0c;这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 014 篇文章&#xff0c;在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验&#xff0c;并希望进…