当前位置: 首页 > news >正文

用冒泡排序模拟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. 完结散花 悟已往之不谏&#xff0c;知来者犹可追 创作不易&#xff0c;宝子们&#xff01;如果这篇文章对你们有帮助的话&#xff0c;别忘了给个免…...

智慧公厕:打造智慧城市环境卫生新标杆

随着科技的不断发展和城市化进程的加速推进&#xff0c;智慧城市建设已经成为各地政府和企业关注的焦点。而作为智慧城市环境卫生管理的基础设施&#xff0c;智慧公厕的建设和发展也备受重视&#xff0c;被誉为智慧城市的新标杆。本文以智慧公厕源头厂家广州中期科技有限公司&a…...

【学习版】Microsoft Office 2021安装破解教程

本文转载自知乎&#xff1a;https://zhuanlan.zhihu.com/p/655653158 由本人二次整理修改 用到的软件为&#xff1a;Office Tool Plus&#xff0c;下载链接&#xff1a;Office Tool Plus 官方网站 - 一键部署 Office (landian.vip) 下载页面&#xff1a;&#xff08;随机找个站…...

基于java Springboot实现课程评分系统设计和实现

基于java Springboot实现课程评分系统设计和实现 博主介绍&#xff1a;多年java开发经验&#xff0c;专注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&#xff0c;全称为You Only Look Once: Unified, Real-Time Object Detection&#xff0c;是一种实时目标检测算法。目标检测是计算机视觉领域的一个重要任务&#xff0c;它不仅需要识别图像中的物体类别&#xff0c;还需要确定它们的位置。与分类任务只关注对…...

【Android】更改手机主题导致app数据丢失问题

情景&#xff1a;在使用app过程中更改系统主题&#xff08;比如从浅色主题改为深色主题&#xff09;&#xff0c;这时activity销毁重建了&#xff08;即走了onPause、onStop、onSaveInstanceState、onDestroy、onCreate、onRestoreInstanceState、onStart、onResume的生命周期&…...

Dell R730 2U服务器实践3:安装英伟达上代专业AI训练Nvidia P4计算卡

Dell R730是一款非常流行的服务器&#xff0c;2U的机箱可以放入两张显卡&#xff0c;这次先用一张英伟达上代专业级AI训练卡&#xff1a;P4卡做实验&#xff0c;本文记录安装过程。 简洁步骤&#xff1a; 打开机箱将P4显卡插在4号槽位关闭机箱安装驱动 详细步骤&#xff1a; 对…...

Nacos环境搭建 -- 服务注册与发现

为什么需要服务治理 在未引入服务治理模块之前&#xff0c;服务之间的通信是服务间直接发起并调用来实现的。只要知道了对应服务的服务名称、IP地址、端口号&#xff0c;就能够发起服务通信。比如A服务的IP地址为192.168.1.100:9000&#xff0c;B服务直接向该IP地址发起请求就…...

Linux了解

简介 Linux是一种自由和开放源代码的类UNIX操作系统&#xff0c;由芬兰的Linus Torvalds于1991年首次发布。Linux最初是作为支持英特尔x86架构的个人电脑的一个自由操作系统&#xff0c;现在已经被移植到更多的计算机硬件平台&#xff0c;如手机、平板电脑、路由器、视频游戏控…...

Keil新版本安装编译器ARMCompiler 5.06

0x00 缘起 我手头的项目在使用最新版本的编译器后&#xff0c;烧录后无法正常运行&#xff0c;故安装5.06&#xff0c;测试后发现程序运行正常&#xff0c;以下为编译器的安装步骤。 0x01 解决方法 1. 下载编译器安装文件&#xff0c;可以去ARM官网下载&#xff0c;也可以使用我…...

【基础训练 || Test-1】

总言 主要内容&#xff1a;一些习题。       文章目录 总言一、选择1、for循环、操作符&#xff08;逗号表达式&#xff09;2、格式化输出&#xff08;转换说明符&#xff09;3、for循环、操作符&#xff08;逗号表达式、赋值和判等&#xff09;4、if语句、操作符&#xff…...

Python读取hbase数据库

1. hbase连接 首先用hbase shell 命令来进入到hbase数据库&#xff0c;然后用list命令来查看hbase下所有表&#xff0c;以其中表“DB_level0”为例&#xff0c;可以看到库名“baotouyiqi”是拼接的&#xff0c;python代码访问时先连接&#xff1a; def hbase_connection(hbase…...

LeetCode41题:缺失的第一个正数(python3)

这道题写的时候完全没有思路&#xff0c;看了很久的题解&#xff0c;才总结出来。 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实体&#xff1a; /// <summary>/// 单个分类表/// </summary>public class DataTableClassfiy{/// <summary>/// 分类名称/// &…...

web运行时安全

1.输入验证 对传递的数据的格式、长度、类型&#xff08;前端和后端都要&#xff09;进行校验。 对黑白名单校验&#xff1a;比如前端传递了一个用户名&#xff0c;可以搜索该用户是否在白名单或者黑名单列表。 针对黑名单校验&#xff0c;比如&#xff1a; // 手机号验证…...

FPGA 与 数字电路的关系 - 这篇文章 将 持续 更新 :)

先说几个逻辑&#xff1a;&#xff08;强调一下在这篇文章 输入路数 只有 1个或2个&#xff0c;输出只有1个&#xff0c;N个输入M个输出以后再说&#xff09; 看下面的几个图&#xff1a; 图一&#xff08; 忘了 这是 啥门&#xff0c;不是门吧 &#xff1a;&#xff09;也就…...

18 SpringMVC实战

18 SpringMVC实战 1. 课程介绍2. Spring Task定时任务1. 课程介绍 2. Spring Task定时任务 package com.imooc.reader.task...

Rocky Linux 运维工具 dnf

一、dnf的简介 dnf​是用于在基于RPM包管理系统的包管理工具。用户可以通过 ​yum​来搜索、安装、更新和删除软件包&#xff0c;自动处理依赖关系&#xff0c;它是yum的继任者&#xff0c;旨在提供更快速、更现代化的软件包管理体验。。 二、dnf 的参数说明 序号参数描述1in…...

浅谈 Linux fork 函数

文章目录 前言fork 基本概念代码演示示例1&#xff1a;体会 fork 函数返回值的作用示例2&#xff1a;创建多进程&#xff0c;加深对 fork 函数的理解 前言 本篇介绍 fork 函数。 fork 基本概念 pid_t fork(void) fork 的英文含义是"分叉"&#xff0c;在这里就是 …...

在rocky linux 9.5上在线安装 docker

前面是指南&#xff0c;后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换

目录 关键点 技术实现1 技术实现2 摘要&#xff1a; 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式&#xff08;自动驾驶、人工驾驶、远程驾驶、主动安全&#xff09;&#xff0c;并通过实时消息推送更新车…...

Mac flutter环境搭建

一、下载flutter sdk 制作 Android 应用 | Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 1、查看mac电脑处理器选择sdk 2、解压 unzip ~/Downloads/flutter_macos_arm64_3.32.2-stable.zip \ -d ~/development/ 3、添加环境变量 命令行打开配置环境变量文件 ope…...

数据结构:泰勒展开式:霍纳法则(Horner‘s Rule)

目录 &#x1f50d; 若用递归计算每一项&#xff0c;会发生什么&#xff1f; Horners Rule&#xff08;霍纳法则&#xff09; 第一步&#xff1a;我们从最原始的泰勒公式出发 第二步&#xff1a;从形式上重新观察展开式 &#x1f31f; 第三步&#xff1a;引出霍纳法则&…...

CSS 工具对比:UnoCSS vs Tailwind CSS,谁是你的菜?

在现代前端开发中&#xff0c;Utility-First (功能优先) CSS 框架已经成为主流。其中&#xff0c;Tailwind CSS 无疑是市场的领导者和标杆。然而&#xff0c;一个名为 UnoCSS 的新星正以其惊人的性能和极致的灵活性迅速崛起。 这篇文章将深入探讨这两款工具的核心理念、技术差…...

手动给中文分词和 直接用神经网络RNN做有什么区别

手动分词和基于神经网络&#xff08;如 RNN&#xff09;的自动分词在原理、实现方式和效果上有显著差异&#xff0c;以下是核心对比&#xff1a; 1. 实现原理对比 对比维度手动分词&#xff08;规则 / 词典驱动&#xff09;神经网络 RNN 分词&#xff08;数据驱动&#xff09…...

【Vue】scoped+组件通信+props校验

【scoped作用及原理】 【作用】 默认写在组件中style的样式会全局生效, 因此很容易造成多个组件之间的样式冲突问题 故而可以给组件加上scoped 属性&#xff0c; 令样式只作用于当前组件的标签 作用&#xff1a;防止不同vue组件样式污染 【原理】 给组件加上scoped 属性后…...

解决MybatisPlus使用Druid1.2.11连接池查询PG数据库报Merge sql error的一种办法

目录 前言 一、问题重现 1、环境说明 2、重现步骤 3、错误信息 二、关于LATERAL 1、Lateral作用场景 2、在四至场景中使用 三、问题解决之道 1、源码追踪 2、关闭sql合并 3、改写处理SQL 四、总结 前言 在博客&#xff1a;【写在创作纪念日】基于SpringBoot和PostG…...