用冒泡排序模拟C语言中的内置快排函数qsort!
目录
编辑
1.回调函数的介绍
2. 回调函数实现转移表
3. 冒泡排序的实现
4. qsort的介绍和使用
5. qsort的模拟实现
6. 完结散花
悟已往之不谏,知来者犹可追
创作不易,宝子们!如果这篇文章对你们有帮助的话,别忘了给个免费的赞哟~
1.回调函数的介绍
这里首先介绍一下回调函数的概念~
回调函数是使用函数指针(地址)调用的函数。
如果我们把一个函数的指针(地址)作为一个参数传递给另一个函数,当我们通过指针找到这个函数并对其进行调用时,这个被调用的函数就是回调函数。
回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应
#include<stdio.h> test(void (*print)()) {print(); } void print() {printf("这是一个回调函数\n"); } int main() {test(print);return 0; }
2. 回调函数实现转移表
现在我们来实现一个简单的计算器~
#include <stdio.h> int add(int a, int b) { return a + b; } int sub(int a, int b) { return a - b; } int mul(int a, int b) { return a * b; } int div(int a, int b) { return a / b; } int main() { int x, y; int input = 1; int ret = 0; do { printf("*************************\n"); printf(" 1:add 2:sub \n"); printf(" 3:mul 4:div \n"); printf(" 0:exit \n"); printf("*************************\n"); printf("请选择:"); scanf("%d", &input); switch (input) { case 1: printf("输⼊操作数:"); scanf("%d %d", &x, &y); ret = add(x, y); printf("ret = %d\n", ret); break; case 2: printf("输⼊操作数:"); scanf("%d %d", &x, &y); ret = sub(x, y); printf("ret = %d\n", ret); break; case 3: printf("输⼊操作数:"); scanf("%d %d", &x, &y); ret = mul(x, y); printf("ret = %d\n", ret); break; case 4: printf("输⼊操作数:"); scanf("%d %d", &x, &y); ret = div(x, y); printf("ret = %d\n", ret); break; case 0: printf("退出程序\n"); break; default: printf("选择错误\n"); break; } } while (input); return 0; }我们可以很容易的观察到上述代码有一部分是多次重复的~
这部分只有函数的调用是不一样的,所以我们是不是可以把这部分封装成一个函数calc(),在calc函数中调用不同的加减乘除函数就行了呢~
#include <stdio.h> int add(int a, int b) {return a + b; } int sub(int a, int b) {return a - b; } int mul(int a, int b) {return a * b; } int div(int a, int b) {return a / b; } void cacl(int(*p)(int x, int y)) {int x = 0;int y = 0;printf("输入操作数:");scanf("%d %d", &x, &y);int ret = p(x, y);printf("ret = %d\n", ret); }int main() {int input = 1;do{printf("*************************\n");printf(" 1:add 2:sub \n");printf(" 3:mul 4:div \n");printf(" 0:exit \n");printf("*************************\n");printf("请选择:");scanf("%d", &input);switch (input){case 1:cacl(add);break;case 2:cacl(sub);break;case 3:cacl(mul);break;case 4:cacl(div);break;case 0:printf("退出程序\n");break;default:printf("选择错误\n");break;}} while (input);return 0; }
3. 冒泡排序的实现
常见的排序有插入排序、选择排序、希尔排序、冒泡排序、快速排序等等~
在讲qsort前,这里我们先了解一下冒泡排序~
顾名思义,冒泡排序就是让元素像泡泡一样慢慢往上移动~
这里我用C语言来实现一下~
void bull_sort(int* arr,int len) {assert(arr);//判断指针的有效性for (int i = 0; i < len - 1; i++){int flag = 1;//假设已经有序for (int j = 0; j < len - 1 - i; j++){if (arr[j] > arr[j + 1]){int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;flag = 0;}}if (flag == 1)break;} } int main() {int arr[] = { 9,8,7,6,5,4,3,2,1,0 };int len = sizeof(arr) / sizeof(arr[0]);bull_sort(arr, len);for (int i = 0; i < len; i++){printf("%d ", arr[i]);}return 0; }运行效果~
4. qsort的介绍和使用
接下来我们就来看看qsort啦~
注意我们在使用qsort时要引入头文件#include<stdlib.h>
这里简单的举个栗子来使用一下qsort啦~
int cmp_int(const void* a, const void* b) {assert(a && b);return *(int*)a - *(int*)b; } int main() {int arr[] = { 9,8,7,6,5,4,3,2,1,0 };int len = sizeof(arr) / sizeof(arr[0]);assert(arr);//判断指针的有效性qsort(arr, len, sizeof(arr[0]), cmp_int);for (int i = 0; i < len; i++){printf("%d ", arr[i]);}return 0;; }效果如下~
我们还可以使用qsort比较结构体类型的变量!
我们通过结构体中的名字来比较结构体变量的大小~
struct S {char name[20];int age; };//定义一个结构体类型 int cmp_stu_by_age(const void* a,const void* b) {return strcmp(((struct S*)a)->name, ((struct S*)b)->name); } int main() {struct S student[3] = { {"zhangsan",18},{"lisi",17},{"wanglaowu",16} };//定义一个结构体数组并初始化int len = sizeof(student) / sizeof(student[0]);qsort(student, len, sizeof(student[0]), cmp_stu_by_age);return 0; }排序前~
排序后~
5. qsort的模拟实现
对比上面我们自己写的冒泡排序和C语言中的内置快排,我们会发现我们自己写的冒泡排序只能对int类型的数据进行排序(有局限性),而qsort却可以对任意类型的数据进行排序。
接下来这里我就使用冒泡排序的算法模拟实现qsort~
int cmp_int(const void* a, const void* b) {assert(a && b);return *(int*)a - *(int*)b; } void swap(char* buf1,char* buf2,size_t num)//一个一个字节交换 {while (num--){char tmp = *(buf1);*(buf1) = *(buf2);*(buf2) = tmp;buf1++;buf2++;} } void my_qsort(void* arr, size_t len, size_t num, int (*cmp_int)(const void*,const void*)) {assert(arr);//判断指针的有效性for (int i = 0; i < len - 1; i++){int flag = 1;//假设已经有序for (int j = 0; j < len - 1 - i; j++){if(cmp_int((char*)arr + j * num, (char*)arr + (j + 1) * num)>0);{swap(((char*)arr + j * num), ((char*)arr + (j + 1) * num),num);flag = 0;}}if (flag == 1)break;} } int main() {int arr[] = { 9,8,7,6,5,4,3,2,1,0 };size_t len = sizeof(arr) / sizeof(arr[0]);my_qsort(arr, len, sizeof(arr[0]), cmp_int);for (int i = 0; i < len; i++){printf("%d ", arr[i]);}return 0; }运行效果如下~
![]()
6. 完结散花
好了,这期的分享到这里就结束了~
如果这篇博客对你有帮助的话,可以用你们的小手指点一个免费的赞并收藏起来哟~
如果期待博主下期内容的话,可以点点关注,避免找不到我了呢~
我们下期不见不散~~


相关文章:
用冒泡排序模拟C语言中的内置快排函数qsort!
目录 编辑 1.回调函数的介绍 2. 回调函数实现转移表 3. 冒泡排序的实现 4. qsort的介绍和使用 5. qsort的模拟实现 6. 完结散花 悟已往之不谏,知来者犹可追 创作不易,宝子们!如果这篇文章对你们有帮助的话,别忘了给个免…...
智慧公厕:打造智慧城市环境卫生新标杆
随着科技的不断发展和城市化进程的加速推进,智慧城市建设已经成为各地政府和企业关注的焦点。而作为智慧城市环境卫生管理的基础设施,智慧公厕的建设和发展也备受重视,被誉为智慧城市的新标杆。本文以智慧公厕源头厂家广州中期科技有限公司&a…...
【学习版】Microsoft Office 2021安装破解教程
本文转载自知乎:https://zhuanlan.zhihu.com/p/655653158 由本人二次整理修改 用到的软件为:Office Tool Plus,下载链接:Office Tool Plus 官方网站 - 一键部署 Office (landian.vip) 下载页面:(随机找个站…...
基于java Springboot实现课程评分系统设计和实现
基于java Springboot实现课程评分系统设计和实现 博主介绍:多年java开发经验,专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文末获取源…...
git操作基本指令
1.查看用户名 git config user.name 2.查看密码 git config user.password 3.查看邮箱 git config user.email 4.修改用户名 git config --global user.name "xxx(新用户名)" 5.修改密码 git config --global user.password "xxx(新密码)" 6.修改…...
YOLO算法
YOLO介绍 YOLO,全称为You Only Look Once: Unified, Real-Time Object Detection,是一种实时目标检测算法。目标检测是计算机视觉领域的一个重要任务,它不仅需要识别图像中的物体类别,还需要确定它们的位置。与分类任务只关注对…...
【Android】更改手机主题导致app数据丢失问题
情景:在使用app过程中更改系统主题(比如从浅色主题改为深色主题),这时activity销毁重建了(即走了onPause、onStop、onSaveInstanceState、onDestroy、onCreate、onRestoreInstanceState、onStart、onResume的生命周期&…...
Dell R730 2U服务器实践3:安装英伟达上代专业AI训练Nvidia P4计算卡
Dell R730是一款非常流行的服务器,2U的机箱可以放入两张显卡,这次先用一张英伟达上代专业级AI训练卡:P4卡做实验,本文记录安装过程。 简洁步骤: 打开机箱将P4显卡插在4号槽位关闭机箱安装驱动 详细步骤: 对…...
Nacos环境搭建 -- 服务注册与发现
为什么需要服务治理 在未引入服务治理模块之前,服务之间的通信是服务间直接发起并调用来实现的。只要知道了对应服务的服务名称、IP地址、端口号,就能够发起服务通信。比如A服务的IP地址为192.168.1.100:9000,B服务直接向该IP地址发起请求就…...
Linux了解
简介 Linux是一种自由和开放源代码的类UNIX操作系统,由芬兰的Linus Torvalds于1991年首次发布。Linux最初是作为支持英特尔x86架构的个人电脑的一个自由操作系统,现在已经被移植到更多的计算机硬件平台,如手机、平板电脑、路由器、视频游戏控…...
Keil新版本安装编译器ARMCompiler 5.06
0x00 缘起 我手头的项目在使用最新版本的编译器后,烧录后无法正常运行,故安装5.06,测试后发现程序运行正常,以下为编译器的安装步骤。 0x01 解决方法 1. 下载编译器安装文件,可以去ARM官网下载,也可以使用我…...
【基础训练 || Test-1】
总言 主要内容:一些习题。 文章目录 总言一、选择1、for循环、操作符(逗号表达式)2、格式化输出(转换说明符)3、for循环、操作符(逗号表达式、赋值和判等)4、if语句、操作符ÿ…...
Python读取hbase数据库
1. hbase连接 首先用hbase shell 命令来进入到hbase数据库,然后用list命令来查看hbase下所有表,以其中表“DB_level0”为例,可以看到库名“baotouyiqi”是拼接的,python代码访问时先连接: def hbase_connection(hbase…...
LeetCode41题:缺失的第一个正数(python3)
这道题写的时候完全没有思路,看了很久的题解,才总结出来。 class Solution:def firstMissingPositive(self, nums: List[int]) -> int:nums_set set(nums)n len(nums)for i in range(1, n 1):if i not in nums_set:return ireturn n 1...
C# DataTable 对象操作
实现DataTable按字段进行分类、按列数据汇总、序列化对象数组、所有字段转小写、动态对象数组、数据分页 分类DataTableClassfiy实体: /// <summary>/// 单个分类表/// </summary>public class DataTableClassfiy{/// <summary>/// 分类名称/// &…...
web运行时安全
1.输入验证 对传递的数据的格式、长度、类型(前端和后端都要)进行校验。 对黑白名单校验:比如前端传递了一个用户名,可以搜索该用户是否在白名单或者黑名单列表。 针对黑名单校验,比如: // 手机号验证…...
FPGA 与 数字电路的关系 - 这篇文章 将 持续 更新 :)
先说几个逻辑:(强调一下在这篇文章 输入路数 只有 1个或2个,输出只有1个,N个输入M个输出以后再说) 看下面的几个图: 图一( 忘了 这是 啥门,不是门吧 :)也就…...
18 SpringMVC实战
18 SpringMVC实战 1. 课程介绍2. Spring Task定时任务1. 课程介绍 2. Spring Task定时任务 package com.imooc.reader.task...
Rocky Linux 运维工具 dnf
一、dnf的简介 dnf是用于在基于RPM包管理系统的包管理工具。用户可以通过 yum来搜索、安装、更新和删除软件包,自动处理依赖关系,它是yum的继任者,旨在提供更快速、更现代化的软件包管理体验。。 二、dnf 的参数说明 序号参数描述1in…...
浅谈 Linux fork 函数
文章目录 前言fork 基本概念代码演示示例1:体会 fork 函数返回值的作用示例2:创建多进程,加深对 fork 函数的理解 前言 本篇介绍 fork 函数。 fork 基本概念 pid_t fork(void) fork 的英文含义是"分叉",在这里就是 …...
idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...












