用冒泡排序完成库函数qsort的作用

在这里插入图片描述
Hello,今天分享的是我们用冒泡函数实现qsort,也就是快排,之前我们也讲过库函数qsort的使用方法,今天我们尝试用冒泡函数实现一下,当然我们也见过qsort,后面也会继续完善的。这几天我是破防大学生,唉!
先来看一下qsort是怎样的,我们可以登录网站cplusplus
在这里插入图片描述
在这里插入图片描述
通过该网站我们可以看到的是qsor的使用方法,首先我们可以看到它的返回类型是void,参数有base,num,size,还有compar我们通过英文可以看到的是base其实就是我们要排序的东西,前面用的是一个void*
的指针,void我们可以把它看成其实就是一个垃圾桶,它什么都能接收,它可以接收数组,也可以是结构体,所以这里void* 说明这个指针指向的类型可以是int 也可以是结构体 也可以是double类型的,反正都可以的。

那我们先写一个冒泡函数是怎样的,相信看过我之前文章的人这个应该会了吧,手撕冒泡排序。

void bubble(int* arr, int sz)
{int i = 0;for (i = 0; i < sz - 1; i++){int j = 0;for (j = 0; i < sz - 1 - i; j++){if (arr[j] > arr[j + 1]){int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = arr[j];}}}
}

来看我们的冒泡程序,第一个循环决定的是我们排序的趟数,比如我们十个元素,难道我们要排序十次吗,其实九次就可以,最后一次已经有序了,那这样就不需要排序了,所以只需要九次,因为我们假设是升序,那就是前一个大于后一个的时候才要交换,所以第一趟的时候我们就可以把最大的数放到最后了,所以我们需要减去i在后面循环的时候。冒泡排序对于大家来说肯定已经很简单了。
那我们模拟实现qsort的时候用冒泡排序该怎么做呢,首先我们可以用qsort的参数

在这里插入图片描述
那我们也就可以这样写void bubble(void* base, int num, int sz, int (*cmp)(const void*, const void*)),这样之后我们需要做的其实和冒泡排序的思路是一样的,第一个循环的趟数,所以我们可以看到的是下面的代码

void bubble(void* base, int num, int sz, int (*cmp)(const void*, const void*))
{int i = 0;for (i = 0; i < num - 1; i++){int j = 0;for (j = 0; j < num - 1 - i; j++){if (cmp((char*)base + j * sz, (char*)base + (j + 1) * sz) > 0){swap((char*)base + j * sz, (char*)base + (j + 1) * sz, sz);}}}
}

我这里就全部放出来了,也比较好解释说明,首先我们比较这里是用一个函数来判断是否大于0,函数该怎么实现呢,这里穿的参数是一个特别重要的地方,为什么这么说,看到代码首先我们先要强转成char*类型,因为这样才方便我们后续的访问,我们可以先来看一下比较函数

int cmp(const void* e1, const void* e2)
{return *(int*)e1 - *(int*)e2;
}

我们比较的是整型,所以我们要先强转成整型,然后才能开始访问解引用的操作,我们接收指针也用void类型,所以这里也有好处,就是我们可以比较任何类型的数据,比如double类型,我们需要改变的就是强转成double类型就可以,结构体也是可以进行排序的,这样是不是满足我们快排可以排很多的数据。
那我们再来完善一下swap函数,看代码发现其实我们传参数是一样的,这是为什么呢,因为我们不知道他是什么类型的数据,那这里需要我们一个一个字符,我们要知道这个类型的数据大小,所有还要传一个sz的参数,那我们来看一下交换函数的代码

void swap(char* e1, char* e2,int sz)
{int i = 0;for (i = 0; i < sz; i++){char tmp = *e1;*e1 = *e2;*e2 = tmp;e1++;e2++;}
}

这里有一个误区,我一开始也犯了,希望大家不要犯,首先我们是传指针过去,写的是char类型,接收的是char*这样的指针,然后交换的不是地址,因为指针就是地址,这个我们是知道的,所以这里我们是交换的是指针指向的字符,我们是一个一个交换的,所以外面还需要且套一个循环,这样才能全部交换,这里就是我们还要传一个参数sz的原因,下面是完整的代码

#include<stdio.h>
void print(int arr[], int sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);}printf("\n");
}
int cmp(const void* e1, const void* e2)
{return *(int*)e1 - *(int*)e2;
}
void swap(char* e1, char* e2,int sz)
{int i = 0;for (i = 0; i < sz; i++){char tmp = *e1;*e1 = *e2;*e2 = tmp;e1++;e2++;}
}
void bubble(void* base, int num, int sz, int (*cmp)(const void*, const void*))
{int i = 0;for (i = 0; i < num - 1; i++){int j = 0;for (j = 0; j < num - 1 - i; j++){if (cmp((char*)base + j * sz, (char*)base + (j + 1) * sz) > 0){swap((char*)base + j * sz, (char*)base + (j + 1) * sz, sz);}}}
}
int main()
{int arr[] = { 9,8,0,5,5,4,3,2,1 };int sz = sizeof(arr) / sizeof(arr[0]);print(arr,sz);bubble(arr, sz, sizeof(arr[0]), cmp);print(arr,sz);return 0;
}

在这里插入图片描述
这里也是成功的实现我们冒泡版的qsort函数,这里先不谈效率,主要是要知道这个思想,我们后面学了八大排序会学的是快排,有三种方式可以实现,所以我们也不需要着急。

今天是在学校里写的第二篇文章,昨天电脑坏了,要重装系统,最近总是不顺利,不顺利的时候就会特别难过,也希望自己这几天能调整好心态,谢谢大家,我们后面接着分享,大家一起进步!!!

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

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

相关文章

Debian11安装PostgreSQL+PostGIS+pgRouting ,链接Navicat

船新版本&#xff0c;遵循官网教程 1 准备一个Debian11系统2 从官网安装Postgres2.1 安装Postgres2.2 修改Postgres密码2.3 配置Postgres远程访问 3 安装Postgis、pgRouting4 链接Navicat 1 准备一个Debian11系统 2 从官网安装Postgres 2.1 安装Postgres 1 进入Postgre的官网…

第一类曲线积分与二重积分在极坐标系下表示的区别

1.第一类曲线积分与二重积分在极坐标系下表示的区别 区别主要来源于一是曲线积分的积分区域为边界&#xff0c;而二重积分的积分区域为内部边界&#xff0c;二是极点位置选取的不同&#xff0c;二者共同造成在积分区域在极坐标下表示的不同&#xff0c;即 ρ \rho ρ是常量还是…

uboot 顶层Makefile-make xxx_deconfig过程说明三

一. uboot 的 make xxx_deconfig配置 本文接上一篇文章的内容。地址如下&#xff1a;uboot 顶层Makefile-make xxx_deconfig过程说明二_凌肖战的博客-CSDN博客 本文继续来学习 uboot 源码在执行 make xxx_deconfig 这个配置过程中&#xff0c;顶层 Makefile有关的执行思路。 …

spring boot+redis整合基础入门

文章目录 前言准备依赖项配置文件redis模板类注入设置序列化方式 实施基础字符串操作、超时设置Hash操作hash的使用场景以及优缺点 列表操作列表操作的应用场景以及优缺点 Set的基础操作Set类型的业务场景以及优缺点Demo地址 总结 前言 最近项目中有用到redis进行一些数据的缓…

导数公式及求导法则

目录 基本初等函数的导数公式 求导法则 有理运算法则 复合函数求导法 隐函数求导法 反函数求导法 参数方程求导法 对数求导法 基本初等函数的导数公式 基本初等函数的导数公式包括&#xff1a; C0(x^n)nx^(n-1)(a^x)a^x*lna(e^x)e^x(loga(x))1/(xlna)(lnx)1/x(sinx)cos…

阿里云服务器配置怎么选择?几核几G?带宽系统盘怎么选?

阿里云服务器配置选择_CPU内存/带宽/存储配置_小白指南&#xff0c;阿里云服务器配置选择方法包括云服务器类型、CPU内存、操作系统、公网带宽、系统盘存储、网络带宽选择、安全配置、监控等&#xff0c;阿小云分享阿里云服务器配置选择方法&#xff0c;选择适合自己的云服务器…

用selenium webdriver获取网站cookie后,实现免登录上网站

以csdn为例&#xff0c;代码分为两部分。 一、csdn_get_cookies.py为半手动登录网站后获取cookies 二、csdn_use_cookies.py为使用获取到的cookies免登录上网站 #获取登录cookiesfrom selenium import webdriver import jsoncsdn_driver webdriver.Chrome() url "htt…

ChatGPT OpenAI 完成Excel组合函数Vlookup+match多条件查找

ChatGPT OpenAI 现在已经助力职场办公。 我们现在有这样一个Excel需求: 根据姓名与科目查找对应的分数。可以使用Vlookup+match组合函数一起来实现 。 我们将公式复制到Excel中来进行验证。 ChatGPT生成的Excel函数公式可以直接进行使用。 更多实战内容。

Android:使用命令行发现keytool不是内部命令解决办法

一、前言&#xff1a;最近在搞引入高德地图的SDK&#xff0c;发现需要给app签名打包。记录一下。 二、当我在命令行中输入keytool的时候说keytool不是内部命令 解决方案&#xff1a; 找到系统属性--------高级----------点击环境变量 双击点开 找到java\jre1.8.0_202\bin新建…

CSS3技巧36:backdrop-filter 背景滤镜

CSS3 有 filter 滤镜属性&#xff0c;能给内容&#xff0c;尤其是图片&#xff0c;添加各种滤镜效果。 filter 滤镜详见博文&#xff1a;CSS3中强大的filter(滤镜)属性_css3滤镜_stones4zd的博客-CSDN博客 后续&#xff0c;CSS3 又新增了 backdrop-filter 背景滤镜。 backdr…

SAP SD之定义装运点OVL2

什么是装运点&#xff1f; 装运点是一个独立的组织实体&#xff0c;其中进行货物的发行和交付处理。 可以为每个订单商品确定一个装运点。 确定装运点取决于以下三个因素&#xff1a; 客户主记录中的运输条款和条件&#xff08;运输屏幕&#xff09;。 例如&#xff0c;公司与…

180B参数的Falcon登顶Hugging Face,vs chatGPT 最好开源大模型使用体验

文章目录 使用地址使用体验test1:简单喜好类问题test2:知识性问题test3:开放性问题test4:中文支持test5:问题时效性test6:学术问题使用地址 https://huggingface.co/spaces/tiiuae/falcon-180b-demo 使用体验 相比Falcon-7b,Falcon-180b拥有1800亿的参数量

程序员面试逻辑题

红白帽子推理 答案&#xff1a; 这个题有点像数学归纳法&#xff0c;就是假设有 A A A和 B B B两个人是黑色的帽子&#xff0c;这样的话第一次开灯&#xff0c; A A A看到 B B B是黑色的&#xff0c;其他人都是白色的&#xff0c;那么 A A A会觉得 B B B是那个黑色的&#xff0…

第28章_瑞萨MCU零基础入门系列教程之基于面向对象的工程结构

本教程基于韦东山百问网出的 DShanMCU-RA6M5开发板 进行编写&#xff0c;需要的同学可以在这里获取&#xff1a; https://item.taobao.com/item.htm?id728461040949 配套资料获取&#xff1a;https://renesas-docs.100ask.net 瑞萨MCU零基础入门系列教程汇总&#xff1a; ht…

c刷题(四)

获得月份天数 获得月份天数_牛客题霸_牛客网 这道题可以用switch case语句解&#xff0c;不过这道题更简单的方法是数组&#xff0c;关键点在于判断是否为闰年。 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include<assert.h> int year_run(int n) …

算法-27.移除元素-⭐

给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出新长度后面…

【基于Cocos Creator 3.5的赛车游戏】8.引入触摸屏幕事件并简单的控制小车

转载知识星球 | 深度连接铁杆粉丝&#xff0c;运营高品质社群&#xff0c;知识变现的工具 项目地址&#xff1a;赛车小游戏-基于Cocos Creator 3.5版本实现: 课程的源码&#xff0c;基于Cocos Creator 3.5版本实现 上一张您已经对Cocos的坐标系有了了解。这一章我们将让小车能…

【经典小练习】JavaSE—拷贝文件夹

&#x1f38a;专栏【Java小练习】 &#x1f354;喜欢的诗句&#xff1a;天行健&#xff0c;君子以自强不息。 &#x1f386;音乐分享【如愿】 &#x1f384;欢迎并且感谢大家指出小吉的问题&#x1f970; 文章目录 &#x1f384;效果&#x1f33a;代码&#x1f6f8;讲解&#x…

微信管理系统在教育行业中的应用

随着教育行业越来越注重科技创新&#xff0c;对微信scrm工具的需求也会越来越大&#xff0c;微信scrm工具在教育行业的市场前景非常广阔&#xff0c;也为教育行业带来更多的发展机遇。 微信SCRM系统由监管、运营两大核心应用组成。能帮助培训机构实现从招生引流、销售管理、再…

【Android知识笔记】UI体系(四)

事件分发原理 屏幕事件会由Linux通过JNI传给WMS(WindowManagerService),然后由WMS传给Activity,最终经过PhoneWindow->DecorView开始往下分发。 View的事件分发 View的事件分发核心源码为 dispatchTouchEvent() 方法: public boolean dispatchTouchEvent(MotionEvent …