qsort函数详解以及模拟实现

news2024/11/26 22:17:20

qsort函数详解以及模拟实现

  • 一.qsort函数是什么
  • 二.具体的使用
    • 1.参数4(参数3在模拟实现时解释)
    • 2.例子
      • 1.排序整形
      • 2.排序结构体
  • 三.模拟实现qsort
    • 1.参数3
    • 2.模拟排序
      • 1.排整形
      • 2.排结构体

在这里插入图片描述

一.qsort函数是什么

qsort全称为quick_sort(快速排序),为什么这么称呼呢?因为它实现的内核就是依靠快排来实现的。但与单纯的快排不同的是,它是库函数并且可以排序任意类型的数据(整数,字符,结构体,字符串…)。

接下来再MSDN里详细看看它的全貌

在这里插入图片描述

可以看到它的头文件是stdlib.h,并且参数很多接下来会详细解析。

在这里插入图片描述

在这里插入图片描述

base

第一个参数是base,在MSDN里的解释是Start of target array。也就是目标数组的开始。

第一个参数传目标数组的起始位置。

num

第二个参数是num,在MSDN里的解释是Array size in elements。也就是数组的大小。

第二个参数传数组的大小。

第三个参数是width,在MSDN里的解释是Element size in bytes。也就是每个成员的大小。

第三个参数是每个元素占的字节大小。

第四个参数是一个函数指针指向compare。在MSDN里的解释是Comparison function。也就是比较功能。

第四个参数传一个函数指针,它所指向的函数要具备比较功能。

二.具体的使用

1.参数4(参数3在模拟实现时解释)

关于函数的参数,参数1,2自然不必多说(要排序自然得知道起始位置和数组大小)。对于参数4,如果我们只需要比较整形,我们自然可以只是向上面的冒泡排序一样直接使用大于比较,但如果是一个字符串呢?如果是一个结构体呢?那么我们当然不能简单的用大于小于这些符号来比较,我们需要自己写一个判断规则,这就是参数4的意义。明确判断规则。也是qsort能排序任意类型数据的关键。

详细说明参数4需要的参数

在这里插入图片描述

1.e1是你需要比较元素的第一个元素的地址,e2是另一个元素的地址。
2.两个参数的类型都是const void *
3.const是为了防止参数在函数内部被改变
4.void*是无具体类型的指针(下面重点说明一下)

在这里插入图片描述

但对于这个函数来说肯定是需要接收不同类型的指针的,各。void*是通用指针。好处是可以接收各种指针,坏处是不能直接解引用,因为连它自己都不知道自己是什么类型。

在这里插入图片描述
在这里插入图片描述

2.例子

1.排序整形

上面说到void*不能直接解引用,所以需要我们进行强制转换。这样才能够使用。ps:由于参数4是函数指针,所以我们应该传函数地址,函数名就表示函数地址。

在这里插入图片描述

这个函数总得有返回值吧,来看看MSDN。

在这里插入图片描述

如果第一个元素小于第二个元素,返回一个小于0的数。如果相等则返回0;如果大于,则返回大于0的数。那么我们就按照它的要求书写。

在这里插入图片描述

来看看结果。

在这里插入图片描述

当然以上是升序,如果想要降序的话直接调个方向就可以了。

在这里插入图片描述

2.排序结构体

在这里插入图片描述

首先按照年龄排成升序

在这里插入图片描述

在这里插入图片描述

可以看到确实按照年龄的升序来排列的。

按照名字来排列

名字是字符串不能直接使用减号,需要用到strcmp。它是按照对应位置字符大小来比较的。

在这里插入图片描述

我们知道该函数需要返回数字,而恰好strcmp满足这个要求。所以我们只需要直接返回strcmp就可以了(注意头文件是string.h)。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

由于l<w<z,所以排序应该是lisi,wangwu,zhangsan,也可以看到确实是这样排序的。

总结:需要排列什么数据取决于参数4所指向的函数如何判断。

三.模拟实现qsort

上文提到qsort是依托快排实现的,但由于快排有些复杂,这里就使用冒泡排序作为内核。(如果还有些不明白的可以看看这篇博客 冒泡排序)

在这里插入图片描述

这是一个简易的冒泡排序,它也能够排列数据。但与qsort不同的是,它只能排列整数。所以接下来我要改造它,使它能够排列任意数据。(ps:这里目前不考虑时间,空间,稳定性之类的)。

上文说过,qsort能排列任意数据,关键在于你写的判断函数,也就是参数4。所以我们也应当对冒泡排序的判断条件进行修改。将它封装为一个函数。

在这里插入图片描述

既然我们要模拟qsort,那么参数也应当于qsort保持一致。ps:为什么要传这些参数,开头已经说过,但参数3还未说过,接下来讲解为什么要传每个元素的宽度。

1.参数3

1.首先我们第一个参数是void * ,也就是我们根本不知道到底传递的是什么类型,我们需要参数3来确定是哪种类型。
2.方便我们找到每个元素(具体使用请看模拟过程)

2.模拟排序

在这里插入图片描述

再次说明参数4是函数指针,它所指向的函数就是我们所写的判断规则,再根据cmp的返回值,如果大于0我们就交换两个数据。接下来的关键是我们如何给cmp传参,也就是我们如何精确的找到这两个元素,然后进行判断。

冒泡排序的内核是相邻两个元素两两进行比较,所以我们com里也应该两两相邻元素进行比较。由于我们根本不知道数据类型,不能使用下标来算,需要用地址来间接寻找,这也体现出了参数3的作用。

在这里插入图片描述

在这里插入图片描述

接下来是如何交换,由于类型不明,我们肯定不能直接交换。但是无论什么元素它的单位都是字节,那么我们可以一个字节一个字节的交换,写一个交换函数挨个交换它们的字节。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

以上就是模拟实现的qsort,任意数据都可以排序,接下来来验证一下。

1.排整形

在这里插入图片描述

2.排结构体

按年龄

在这里插入图片描述

按名字

在这里插入图片描述

总结:由于qsort需要适合各种类型,所以我们传参除了部分明确的外都是void。qsort如何精确的找到两个数依赖于数据的地址。不同类型数据的比较方法是不同的,所以需要我们自己写判断规则。

在这里插入图片描述

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

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

相关文章

Tomcat的基本使用

1, Tomcat 1.1 简介 1.1.1 什么是Web服务器 Web服务器是一个应用程序&#xff08;软件&#xff09;&#xff0c;对HTTP协议的操作进行封装&#xff0c;使得程序员不必直接对协议进行操作&#xff0c;让Web开发更加便捷。主要功能是"提供网上信息浏览服务"。 Web服…

C语言rewind()函数:将文件指针重新指向文件开头

rewind()函数用于将文件指针重新指向文件的开头&#xff0c;同时清除和文件流相关的错误和eof标记&#xff0c;相当于调用fseek(stream, 0, SEEK_SET)&#xff0c;其原型如下&#xff1a; void rewind(FILE * stream); 【参数】stream为已打开文件的指针。 注意&#xff1a;准…

深入理解Pytorch中的分布式训练

作者&#xff1a;台运鹏 (正在寻找internship...)主页&#xff1a;https://yunpengtai.top鉴于网上此类教程有不少模糊不清&#xff0c;对原理不得其法&#xff0c;代码也难跑通&#xff0c;故而花了几天细究了一下相关原理和实现&#xff0c;欢迎批评指正&#xff01;关于此部…

【Python • 字符串】巧用python字符串切片

文章目录前言字符串切片常用用法理解一个字符串逆向下标的字符串字符串切片截取下标a到b的字符串取下标a以后的所有字符串取下标a以前的所有字符串间隔n个字符取字符串字符串逆序输出从下标a的字符开始逆序取字符串逆序输出从b到a的字符串逆序间隔一个字符串输出总结前言 在py…

站酷基于服务网格ASM的生产实践

作者&#xff1a;服务网格ASM 背景介绍 站酷&#xff08;ZCOOL&#xff09;2006 年 8 月创立于北京&#xff0c;深耕设计领域多年&#xff0c;聚集了 1500 万设计师、摄影师、插画师、艺术家、创意人&#xff0c;在设计创意群体中具有一定的影响力与号召力。站酷在创立之初&am…

企业数字化转型“核心方法论”

一、什么是数字化转型&#xff1f;数字化转型是近年来&#xff0c;很多企业老生常谈的话题。那么听了这么多数字化转型的故事&#xff0c;你对其真正了解多少呢&#xff1f;下面织信就数字化转型的背景、以及多个示例的讲解&#xff0c;带你深入理解“数字化转型”这一概念。&a…

构建自组织团队,让敏捷管理更好地落地

敏捷开发是以用户的需求为核心&#xff0c;通过不断迭代、小步快跑、循序渐进的方法进行软件产品的研发&#xff0c;在迭代研发过程中的产品都需要经过测试&#xff0c;具备可视化、可集成和可运行使用的特征。 在团队方面&#xff0c;敏捷开发倡导团队协作&#xff0c;强调个…

React(coderwhy)- 05(redux)

Redux的核心思想 理解JavaScript纯函数 ◼ 函数式编程中有一个非常重要的概念叫纯函数&#xff0c;JavaScript符合函数式编程的范式&#xff0c;所以也有纯函数的概念&#xff1b;  在react开发中纯函数是被多次提及的&#xff1b;  比如react中组件就被要求像是一个纯函数…

数据库迁移到达梦的一些记录

1 达梦迁移工具 参考MySQL迁移到达梦-超出定义长度问题 使用你设置的配置&#xff0c;即可&#xff0c;因为达梦默认采用按照字节存储&#xff0c;mysql是按照字符存储&#xff0c;故而他认为越界了。 使用3.5G数据&#xff0c;342张表进行数据迁移验证 第一此执行,结果 任务…

linux安装mysql以及允许外网访问mysql

下载社区版本 下载最新版 下载历史版本 点击 Archives 文件上传云服务器 /opt/mysql 存放目录随便 添加用户组 groupadd mysql useradd -r -g mysql mysql删除mariadb rpm -qa|grep mariadbrpm -e --nodeps mariadb-libs安装 解压tar -xvf mysql-5.7.20-1.el7.x86_64…

中国企业邮箱安全性研究报告

声明 本文是学习中国企业邮箱安全性研究报告. 下载地址 http://github5.com/view/55003而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 奇安信网神邮件威胁检测系统 奇安信网神邮件威胁检测系统是奇安信集团面向政府、企业、金融、军队等大型企事业单…

javaEE初阶 — 阻塞队列

文章目录阻塞队列1. 概念与特性2. 生产者与消费者模型2.1 生产者消费者模型的两个好处&#xff08;主要的&#xff09;3. 标准库中的阻塞队列3.1 代码实现生产者消费者模型4. 阻塞队列实现4.1 普通队列实现4.2 给队列追加阻塞功能阻塞队列 1. 概念与特性 阻塞队列 是一种特殊的…

Centos 安装Datax及Datax-web

异构数据的采集&#xff0c;方案还是比较多样&#xff0c;除了基于大数据平台的一些集成&#xff1b;简单的数据源&#xff0c;可以直接使用阿里开源的datax来实现&#xff1b;datax-web则是datax界面化操作的开源框架&#xff0c;集成了datax异构数据采集和任务调度的功能。关…

【Kubernetes | Pod 系列】 Pod 的生命周期 Ⅱ —— 容器重启策略

目录题5.4 容器重启策略示例&#xff08;1&#xff09;Always 策略&#xff08;2&#xff09;OnFailure 策略&#xff08;3&#xff09;Never 策略5.4 容器重启策略 在 Pod 的 YAML 清单的 spec 中包含一个 restartPolicy 字段&#xff0c;其可能取值包括 Always&#xff08;…

Jdbc配置文件连接mysql8.0——批量增删改查操作

目录 一、批量插入数据 (一)在DogDao中新增一个功能saveDogList (二)DogDaoImpl实现类中定义字符串拼接实现功能saveDogList (三)DogTest测试 (四)批量插入运行结果 (五)优化后的批量插入 1.DogDao接口中还是使用原来的新增功能saveDog 2. DogDaoImpl实现类中实现saveD…

DOS、DDos攻击详解

目录 一、DDOS 是什么&#xff1f; 二、DDoS的危害 三、常见的DOS攻击 四.DDoS的防范 一、DDOS 是什么&#xff1f; DoS为Denial of Service的简称&#xff0c;意思是拒绝服务。DoS攻击是一种使被攻击者无法正常提供服务的攻击 来解释一下&#xff0c;DDOS 是什么。 举例…

esxi6.0安装

一、安装exsi需要注意的事项&#xff1a; 1.进入BIOS做raid 不同硬件厂商进入bios的方式各不相同&#xff0c;请自行查阅相关资料 RAID 0的特点&#xff1a; 最少需要两块磁盘 数据条带式分布 没有冗余&#xff0c;性能最佳(不存储镜像、校验信息) 不能应用于对数据安全性要求…

代码随想录回溯总结

文章目录0、 前言1、回溯的定义2、回溯解决那些问题3、回溯模板4、问题详解4、1组合问题&#xff1a;[4.1.1 组合](https://leetcode.cn/problems/combinations/)[4.1.2 组合总和 II](https://leetcode.cn/problems/combination-sum-ii/)4.1.3 组合的其他问题4.2排列问题4.2.1[…

3.Isaac入门

Isaac入门 本节提供有关如何开始开发和运行 Isaac 应用程序的指南。 文章目录Isaac入门教程和示例应用程序运行应用程序应用程序控制台选项在 Jetson 上部署和运行Python 应用程序支持使用分布式工作区使用 Docker安装依赖创建 Isaac SDK 开发镜像教程和示例应用程序 有一个可…

【运维有小邓】实时告警通知

当网络上发生特定事件时&#xff0c;EventLog Analyzer可以通过多种方式进行响应。EventLog Analyzer可以实时生成告警 - 发送电子邮件或短信通知给指定的接收者 - 或运行由管理员提供的自定义脚本。通过所提供的多个选项&#xff0c;用户可以确保不会错过任何安全事件。EventL…