编写基于冒泡排序算法的qsort函数
目录
1.简单认识冒泡排序
2.进入正文分析如何实现函数
3.1比较两个相邻元素的大小
3.2比较两个相邻元素大小后要换函数
4.my_qsort函数:
5.总结:
1.简单认识冒泡排序
冒泡排序的步骤如下:
- 比较相邻的两个元素,如果第一个元素比第二个元素大(或小),就交换它们的位置。
- 对每一对相邻的元素重复上述操作,直到数组的末尾。这样,最大(或最小)的元素就被移动到了数组的最后一个位置。
- 除了最后一个元素外,对剩余的元素重复以上步骤,直到没有任何一对相邻元素需要交换为止
// 冒泡排序
void bubble_sort(int arr[], int len)
{int i, j, temp;for (i = 0; i < len - 1; i++){for (j = 0; j < len - 1 - i; j++){if (arr[j] > arr[j + 1]){temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}
}
我们可以基于冒泡排序思想对以上代码进行改造成qsort函数对任意数据类型起到排序作用
了解qsort函数可以看下面的网站或者我的另一篇博客:
cplusplus网站:https://legacy.cplusplus.com/reference/cstdlib/qsort/?kw=qsort
关于qsort函数的使用博客:qsort库函数的使用_Jamo@的博客-CSDN博客
2.进入正文分析如何实现函数
我们通过观察冒泡函数可以看出我们在最初给的冒泡函数中只能比较整型数据来进行排序

在冒泡函数中的第二个for循环中我们通过每一趟冒泡来依次比较两个相邻的元素大小来决定是否交换他们的位置,但如果我们在想要排序的数组中遇到了浮点型数据呢?又或是字符型数据呢?又或是结构体类型数据呢?
显然此时的冒泡函数无法解决我们的燃眉之急。
但我们依然可以借助于冒泡的模板来写出自己的qsort函数来解决问题:
- 我们发现在排序时我们只是排序的数据类型不一样了,但排序思想任然是冒泡思想,因此我们做出的改变就是对第二个for循环中的比较方法就行改进。
3.1比较两个相邻元素的大小
对于int 类型数据我们可以通过大于小于来直接比较他们的大小来决定是否交换位置
对于所有类型来说我们可以实现一个比较函数来帮我们解决这个问题:
//在比较两个相邻元素大小时,由于不知道跳过元素有多大,因此在处理不确定数据类型排序时,使用char * 类型和原数据类型size大小来找到冒泡排序的下两对元素compar((char*)数据1 , (char*)数据2 )
//基于冒泡排序算法的qsort函数
void bubble_qsort(void* base, size_t num, size_t size, int (*compar)(const void* e1, const void* e2))
{int i = 0;int j = 0;int tmp = 0;for (i = 0; i < num - 1; i++){//为了处理不同数据类型比较方法,此处的排序需要在原来整型数据冒泡排序写法上进行改造for (j = 0; j < num - 1 - i; j++){//在为比较函数compar找两两元素时,由于不知道跳过元素有多大,因此在处理不确定数据类型排序时,使用char * 类型和原数据类型size大小来找到冒泡排序的下两对元素//比如说比较元素是int类型时(char*)base加上循环变量j * int类型大小4找到数组首个元素地址,第二个元素地址便是(cahr*)base加上循环变量(j+1)之后 *4 找到第二个元素地址if (compar((char*)base + j * size, (char*)base + (j + 1) * size) > 0){//交换swap((char*)base + j * size, (char*)base + (j + 1) * size, size);}}}
}
以比较整型数据举例:我们自己使用qsort函数时写出自己想要比较的数据类型的compar函数:
//比较函数
//返回大于0的数字代表前一个元素大于后一个元素
//返回等于0的数字代表前一个元素等于后一个元素
//返回小于0的数字代表前一个元素小于后一个元素
int compar(const void* e1, const void* e2)
{return *(int*)e1 - *(int*)e2;
}
3.2比较两个相邻元素大小后要换函数
我们通过自己写一个swap函数来解决这一问题;
为什么要自己写交换函数而不用第三个变量来进行两两交换呢?
我们既然是为了写出一个qsort函数比较任意数据类型数据那我们自然也不知道我们将来要交换的元素究竟是什么类型的,自然也无法创建第三个变量来使其两两交换
实现swap函数:
//给swap函数初始化参数与交换函数compar同理
swap((char*)base + j * size, (char*)base + (j + 1) * size, size);//由于不知道交换元素的类型,因此我们决定对相邻两个元素一个字节一个字节进行交换
//将两元素
void swap(char* p1, char* p2, size_t size)
{int i = 0;for (i = 0; i < size; i++){char tmp = *p1;*p1 = *p2;*p2 = tmp;p1++;p2++;}
}
4.my_qsort函数:
//此交换函数原理是对内存中相邻元素一个字节一个字节交换
void swap(char* p1, char* p2, size_t size)
{int i = 0;for (i = 0; i < size; i++){char tmp = *p1;*p1 = *p2;*p2 = tmp;p1++;p2++;}}
//比较函数
//返回大于0的数字代表前一个元素大于后一个元素
//返回等于0的数字代表前一个元素等于后一个元素
//返回小于0的数字代表前一个元素小于后一个元素
int compar(const void* e1, const void* e2)
{return *(int*)e1 - *(int*)e2;
}//基于冒泡排序算法的qsort函数
void bubble_qsort(void* base, size_t num, size_t size, int (*compar)(const void* e1, const void* e2))
{int i = 0;int j = 0;int tmp = 0;for (i = 0; i < num - 1; i++){//为了处理不同数据类型比较方法,此处的排序需要在原来整型数据冒泡排序写法上进行改造for (j = 0; j < num - 1 - i; j++){//不知道跳过元素有多大,因此在处理不确定数据类型排序时,使用char * 类型和原数据类型size大小来找到冒泡排序的下两对元素//返回大于0的数字代表前一个元素大于后一个元素//返回等于0的数字代表前一个元素等于后一个元素//返回小于0的数字代表前一个元素小于后一个元素if (compar((char*)base + j * size, (char*)base + (j + 1) * size) > 0){//交换swap((char*)base + j * size, (char*)base + (j + 1) * size, size);}}}
}
int main()
{int num_arr[10] = { 10,9,8,7,6,5,4,3,2,1 };int sz = sizeof(num_arr) / sizeof(num_arr[0]);printf("原来的顺序:");print_arr(num_arr, sz);bubble_qsort(num_arr, sz, sizeof(num_arr[0]), compar);printf("排序的顺序:");print_arr(num_arr, sz);return 0;
}
5.总结:
实现该函数最主要的部分便是交换函数compar函数参数的书写,如何在不知道元素数据类型的情况下找到元素来进行大小比较,以及如何在不知道元素数据类型的情况下对两个相邻元素来交换。
以上便是全部内容了,感谢大家的支持和鼓励,下次见!
相关文章:
编写基于冒泡排序算法的qsort函数
目录 1.简单认识冒泡排序 2.进入正文分析如何实现函数 3.1比较两个相邻元素的大小 3.2比较两个相邻元素大小后要换函数 4.my_qsort函数: 5.总结: 1.简单认识冒泡排序 冒泡排序的步骤如下: 比较相邻的两个元素,如果第一个元素比…...
有什么推荐使用的企业上网行为管理软件?
在当今信息化社会,企业的上网行为管理越来越重要。企业上网行为软件是一种能够监控和管理企业员工上网行为的工具,它可以帮助企业更好地管理网络资源,提高工作效率,保护企业信息安全,并符合相关的法律法规。本文将深入…...
机器学习第五课--广告点击率预测项目以及特征选择的介绍
这个项目的主要的目的是通过给定的广告信息和用户信息来预测一个广告被点击与否。 如果广告有很大概率被点击就展示广告,如果概率低,就不展示。 因为如果广告没有被点击,对双方(广告主、平台)来讲都没有好处。所以预测…...
细说tcpdump的妙用
原文地址:EMC中文支持论坛https://community.emc.com/go/chinese 介绍 tcpdump命令最初设计用于观察TCP/IP性能问题,它是一个用于截取网络分组,并输出分组内容的工具。tcpdump可以将网络中传送的数据包的报文头完全截获下来提供分析,它支持针…...
【深度学习实验】前馈神经网络(七):批量加载数据(直接加载数据→定义类封装数据)
目录 一、实验介绍 二、实验环境 1. 配置虚拟环境 2. 库版本介绍 三、实验内容 0. 导入必要的工具包 1. 直接加载鸢尾花数据集 a. 加载数据集 b. 数据归一化 c. 洗牌操作 d. 打印数据 2. 定义类封装数据 a. __init__(构造函数:用于初始化数据集对象) b.…...
气体放电模拟装置中1Pa~101kPa范围内的真空度控制技术
摘要:针对微间隙气体放电特性分析中需要对不同真空压力进行精密控制的要求,本文提出了相应的解决方案。解决方案采用了双路调节技术,由真空计、电控针阀和真空压力控制器组成进气和排气控制回路,可实现真空度1Pa~101kPa全量程范围…...
华为OD机试 - 构成正方形的数量 - 数据结构map(Java 2023 B卷 100分)
目录 专栏导读一、题目描述二、输入描述三、输出描述四、Java算法源码五、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试(JAVA)真题(A卷B卷)》。 …...
sql on条件判断是要注意null值
我是因为用了merge into语法,然后on条件中判断的字段是可配置的,这就导致了,有时候判断条件多的情况下,判断的字段会碰到有null值的情况,如果on两边的字段都是null,null和null对比就会导致结果为false&…...
9.22(一):数组扁平化
ES6的flat方法 const arr[1,2,[33,44,5,[6,7]],3]// es6中的flat方法function arr1() { //数组自带的扁平化方法,flat的参数代表的是需要展开几层, //如果是Infinity的话,就是不管嵌套几层,全部都展开return arr.flat(Infinity) } let resul…...
【vue2第十九章】手动修改ESlint错误 和 配置自动化修改ESlint错误
目标:认识代码规范 代码规范:一套写代码的约定规则。例如:“赋值符号的左右是否需要空格”,"一句结束是否是要加;”等 为什么要使用代码规范? 在团队开发时,提高代码的可读性。 在创建项目时,我们选择的就是一套完整的代码…...
计算机网络常见面试题
目录 一、谈一谈对OSI七层模型和TCP/IP四层模型的理解? 答:OSI七层模型主要分为: TCP/IP四层协议: 二、谈谈TCP协议的3次握手过程? 三、TCP协议为什么要3次握手?2次,4次不行吗? …...
springboot整合MeiliSearch轻量级搜索引擎
一、Meilisearch与Easy Search点击进入官网了解,本文主要从小微型公司业务出发,选择meilisearch来作为项目的全文搜索引擎,还可以当成来mongodb来使用。 二、starter封装 1、项目结构展示 2、引入依赖包 <dependencies><dependenc…...
禁用鼠标的侧边按键
新买了个鼠标,整体都不错,就是鼠标左侧有两个按键,大拇指经常无意触碰到,造成误操作。 就想着关闭侧边按键功能。以下这批文章帮了大忙! 鼠标侧键屏蔽,再也不用担心按到侧键了。_禁用鼠标侧键_挣扎的蓝藻…...
【C语言】数组和指针刷题练习
指针和数组我们已经学习的差不多了,今天就为大家分享一些指针和数组的常见练习题,还包含许多经典面试题哦! 一、求数组长度和大小 普通一维数组 int main() {//一维数组int a[] { 1,2,3,4 };printf("%d\n", sizeof(a));//整个数组…...
2023年中国研究生数学建模竞赛D题解题思路
为了更好的帮助大家第一天选题,这里首先为大家带来D题解题思路,分析对应赛题之后做题阶段可能会遇到的各种难点。 稍后会带来D题的详细解析思路,以及相关的其他版本解题思路 成品论文等资料。 赛题难度评估:A、B>C>E、F&g…...
在编译源码的环境下,搭建起Discuz!社区论坛和WordPress博客的LNMP架构
目录 一.编译安装nginx 二.编译安装MySQL 三.编译安装PHP 四.安装论坛 五.安装wordpress博客 六.yum安装LNMP架构(简要过程参考) 一.编译安装nginx 1)关闭防火墙,将安装nginx所需软件包传到/opt目录下 systemctl stop fire…...
腾讯面试题:无网络环境,如何部署Docker镜像?
亲爱的小伙伴们,大家好!我是小米,很高兴再次和大家见面。今天,我要和大家聊聊一个特别有趣的话题——腾讯面试题:无网络环境,如何部署Docker镜像?这可是一个技术含量颇高的问题哦!废…...
医学影像信息(PACS)系统软件源码
PACS系统是PictureArchivingandCommunicationSystems的缩写,与临床信息系统(ClinicalInformationSystem,CIS)、放射学信息系统(RadiologyInformationSystem,RIS)、医院信息系统(HospitalInformationSystem,HIS)、实验室信息系统(L…...
【01】FISCOBCOS的系统环境安装
我们选择ubuntu系统 01 https://www.ubuntu.org.cn/global 02 03下载最新版 04等待下载 00提前准备好VM,点击创建新的虚拟机 01选择自定义安装 02一直下一步到 03 04 05其他的默认即可 06 07 08 09 10 11一直默认到下面 12 13等待安装 安装后重启即可…...
flutter 权限和图片权限之前的冲突
权限插件 permission_handler: ^9.2.0想调起相册和视频,这个插件只有Permission.storage.request().,获取存储权限。 问题是android 13的一些手机,系统设置没有存储权限,用了上面这个权限,三次拒绝后就永久拒绝了&…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...
在 Spring Boot 项目里,MYSQL中json类型字段使用
前言: 因为程序特殊需求导致,需要mysql数据库存储json类型数据,因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...
Xela矩阵三轴触觉传感器的工作原理解析与应用场景
Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知,帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量,能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度,还为机器人、医疗设备和制造业的智…...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...
全面解析数据库:从基础概念到前沿应用
在数字化时代,数据已成为企业和社会发展的核心资产,而数据库作为存储、管理和处理数据的关键工具,在各个领域发挥着举足轻重的作用。从电商平台的商品信息管理,到社交网络的用户数据存储,再到金融行业的交易记录处理&a…...
