使用冒泡排序模拟qsort

news2025/1/14 0:55:26

目录

冒泡排序🐒:

冒泡排序特点👀:

模拟&改造🔧:

1、让冒泡排序能够接受其他的数据类型,使用参数的改造。🚗

2、比较的方式进行改造❤

思路分析🧠:

 3、交换的代码需要改造🏃‍

 cmp的回调👅:

🕵️‍最终代码演示: 


冒泡排序🐒:

http://t.csdn.cn/HQfDO      

冒泡排序特点👀:

1、利用数组中的元素进行俩两比较,和循环的多次遍历进行排序,得到一个升序或者降序的排列顺序。


2、但是效率过于底下,以及通过qsort的对比,冒泡排序只能用于整型(int)数组的比较和排列,对于其他数据类型的数组比较,显得无能为力。


3、而且,效率底下,运算需要进行多次的遍历,需要设定另外的变量值,进行急刹车,才能避免不必要的遍历循环。

模拟&改造🔧:

1、让冒泡排序能够接受其他的数据类型,使用参数的改造。🚗

  • int arr[] ——void*base  利用void*接收任意类型的地址
  • int sz ——size_t sz  因为void* 所以要有sz进行元素大小的判定,以便接下来移动指针
  • 增加 size_t width   因为void* 所以要有width得知每个元素的字节大小,以便接下来移动指针
  • 增加int(*cmp)(const void*,constvoid*) 使用comaprt 进行函数回调,一次进行两个元素之间的大小比较
void bubble_sort(void* base, size_t sz, size_t width, int (*cmp)(const void*el, const void*e2))

2、比较的方式进行改造❤

原先的比较方式:if (arr[j] > arr[j + 1])


  • 原本的比较方式是基于整型数组的原理上,进行前后元素的比较。 
  • 现在,数据的类型发生了改变,变成了void*这种通用类型。
  • 站在程序员的角度,程序员是不明白用户在传输时究竟是哪一种的数据类型,所以不能直接指定某一种数据类型进行比较
  • 这是一个 if  语句,而compart的判断原理是两个数字之间的比较返值。 
  • 需要交换的条件究竟是什么?是需要升序?还是需要降序?

 

if(cmp((char*)base+j*width,(char*)base +(j+1)*width) > 0)

思路分析🧠:


if(cmp()>0) 其实是利用了cmp的返回值原理   

  • return(前一个元素   减    后一个元素)
  • 返回值大于0 则表示前一个元素大于后一个元素
  • 返回值小于0 则表示前一个元素小于后一个元素
  • 返回值等于0 则表示两个元素的数值是相等的

♥♥(char*)base+j*width  

  •     前文说过,站在程序员的角度,我们是不知晓用户传输的数据类型,但是对于char*来说有一个特有的优势。
  •     char*在进行访问字节的过程中,char*base+1 是只能访问一个字节的,而相对于其他,列如:int*base+1 是一次访问了四个字节。
  •     对于char*一次只能访问一个字节的特点,我们可以利用width以及下标 j 相结合组合成一个适合char*能够从首元素地址出发,指向某个元素的地址,的运算方式。

 

 3、交换的代码需要改造🏃‍


原先交换的代码:

                              int tmp = arr[j];

                              arr[j] = arr[j + i];

                              arr[j + 1] = tmp;


  • 原先交换的代码是基于整型数组的原理上进行的。
  • 交换时,我们的指针类型是否需要进行改变?若不需要进行再次的转变,那么该如何进行交换?
Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);

在面对交换问题的同时,为了简化或是说将整个代码进行简洁化,我们采用了函数调用的方式,以此解决问题。 

void Swap(char* buf1, char* buf2, size_t width)
{
   int i = 0;
   for (i = 0; i < width; i++)//利用遍历,进行字节和字节之间的交换
   {
      char tmp = *bufl;
      *buf1 = *buf2;
      *buf2 = tmp;
      buf1++:
      buf2++;
   }

}

 还是引用前文的话,站在程序员的角度,我们无法知晓用户传输的数据类型究竟是什么,所以在此处无法进行数据类型的转化,所以还是使用char*进行交换。


而char*在前文也有提过,是char*base+1只能访问一个字节,所以我们可以利用循环的遍历,将宽度作为循环的最大次数,以此来进行字节和字节之间的交换,直到抵达相对应的字节大小(宽度)。

 cmp的回调👅:

int cmp(const void* e1, const void* e2)
{
   return *(int*)el - *(int*)e2;
}
  •  因为,cmp 在 qsor的 int  (*cmp)(const void*,const void*) 以及 在前文的 if 判定返值中必须是int整型类型的。
  • 也同时,cmp 是单独独立的一个函数调用,是独立的函数,进行修改时,并不会涉及其他函数的使用,所以此处便可直接进行指针数据类型的转化。
  • 最后,如果要更换数据类型进行比较,也只需要修改主函数的内容和cmp的回调内容即可。

🕵️‍最终代码演示: 

void Swap(char* buf1, char* buf2, size_t width)//交换
{
	int i = 0;
	for (i = 0; i < width; i++)//利用遍历,进行字节和字节之间的交换
	{
		char tmp = *buf1;
		*buf1 = *buf2;
		*buf2 = tmp;
		buf1++;
		buf2++;
	}

}
void BB(void* base, size_t sz, size_t width, int(*cmp)(const void*, const void*))//冒泡排模拟qsort
{
	int i = 0;
	for (i = 0; i < sz - 1; i++)//i表示排序的趟数,和冒泡排序一样的意思
	{
		int j = 0;
		for (j = 0; j < sz - 1 - i; j++)//j表示下摆,和冒泡排序一样的意思
		{
			if (cmp((char*)base + j * width,(char*)base + (j + 1) * width) > 0)//接收返回值
			{
				Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
			}
		}
	}
}

int cmp(const void*e1 , const void* e2)//进行返回值
{
	return *(int*)e1 - *(int*)e2;
}
void print(int* arr, int sz)//打印
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
}
void test1()
{
	int arr[] = { 3,1,5,2,4,8,7,9,10,11,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	BB(arr, sz, sizeof(arr[0]), cmp);//进行比较的函数,cmp回调
	print(arr, sz);//打印数组
}
int main()
{
	test1();
	return 0;
}

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

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

相关文章

unity中导入自定义模型

unity中导入自定义模型 准备软件步骤1从SoildWorks中导出模型为STEP格式2将STEP格式文件导入到3DS Max中&#xff0c;再导出为FBX格式3将FBX格式导入至unity中 准备软件 需要SoildWorks、3DS Max和Unity 3D软件步骤 1从SoildWorks中导出模型为STEP格式 2将STEP格式文件导入到…

[PyTorch][chapter 52][迁移学习]

前言&#xff1a; 迁移学习&#xff08;Transfer Learning&#xff09;是一种机器学习方法&#xff0c;它通过将一个领域中的知识和经验迁移到另一个相关领域中&#xff0c;来加速和改进新领域的学习和解决问题的能力。 这里面主要结合前面ResNet18 例子&#xff0c;详细讲解一…

如何用chatGPT回答女朋友的死亡问题

引言 在爱情的迷雾中&#xff0c;女友的死结问题常常令人犯难。然而&#xff0c;借助ChatGPT的智慧&#xff0c;或许能够开辟一片全新的天地。其独到的见解和无限的可能性&#xff0c;或将为我们的情感困惑带来意想不到的解答。正如科技在塑造我们的生活&#xff0c;也或许能为…

家居行业,瞄准软文营销

对于很多家居品牌来说&#xff0c;传统营销形式越来越无法打动他们&#xff0c;在以渠道为王的环境下&#xff0c;家居品牌更需要思考地是&#xff1a;要带给消费者新的价值和体验究竟是什么&#xff1f; 因为在目前的大环境下&#xff0c;在内容信息上展现的生动性、直接性上、…

Spark SQL优化:NOT IN子查询优化解决

背景 有如下的数据查询场景。 SELECT a,b,c,d,e,f FROM xxx.BBBB WHERE dt ${zdt.addDay(0).format(yyyy-MM-dd)} AND predict_type not IN ( SELECT distinct a FROM xxx.AAAAAWHERE dt ${zdt.addDay(0).format(yyyy-MM-dd)} ) 分析 通过查看SQL语句的执行计划基本…

全面管控企业资产,这个小妙招做到了!

随着全球金融市场的复杂性增加以及资产多样化的趋势&#xff0c;确保资产的最大价值和最小风险已经成为一个迫切的需求。资产管理系统能够更好地掌握自己的财务状况&#xff0c;做出明智的决策。 从个人投资者到大型企业&#xff0c;都可以从中受益&#xff0c;无论是实时监控投…

腾讯云GPU服务器GN7实例NVIDIA T4 GPU卡

腾讯云GPU服务器GN7实例搭载1颗 NVIDIA T4 GPU&#xff0c;8核32G配置&#xff0c;系统盘为100G 高性能云硬盘&#xff0c;自带5M公网带宽&#xff0c;系统镜像可选Linux和Windows&#xff0c;地域可选广州/上海/北京/新加坡/南京/重庆/成都/首尔/中国香港/德国/东京/曼谷/硅谷…

C#如何打包EXE程序生成setup安装文件

项目结束之后&#xff0c;有需要将winForm程序打包成.exe文件提供给用户。 这里记录一下打包过程。 1&#xff1a;首先获取打包插件&#xff0c;如果你的VS已经安装&#xff0c;忽略此步骤。 点击 工具->扩展和更新&#xff0c;选择联机&#xff0c;搜索installer&#x…

AntPro 模版代码

1 ProTable 实现选择和反显 页面1 页面2 选择页面2选择之后反显到页面1 &#xff0c;且支持跨页选择。同时下次进来页面1展示的数据要反显到页面2被选中。 页面2代码 <ProTablerowKey"id"columns{columns}request{(params: any) > {const newParams {pageI…

androidstudio引入jar包

如图&#xff0c;选择project 然后在src下创建一个lib文件夹&#xff0c;将要添加到项目中的jar包粘贴lib里面&#xff0c;如图 接着选中jar包&#xff0c;右击&#xff0c;会出一个弹窗&#xff0c;选择Add As Library…&#xff0c;如图 会出现一个弹窗&#xff0c;点击OK…

安防监控视频云存储平台EasyCVRH.265转码功能更新:新增分辨率配置

安防视频集中存储EasyCVR视频监控综合管理平台可以根据不同的场景需求&#xff0c;让平台在内网、专网、VPN、广域网、互联网等各种环境下进行音视频的采集、接入与多端分发。在视频能力上&#xff0c;视频云存储平台EasyCVR可实现视频实时直播、云端录像、视频云存储、视频存储…

<kernel>kernel 6.4 USB-之-hub_event()分析

&#xff1c;kernel&#xff1e;kernel 6.4 USB-之-hub_event()分析 本文是基于linux kernel 6.4版本内核分析&#xff1b;源码下载路径&#xff1a;linux kernel 本文主要分析hub_event()函数的内容&#xff1b;hub_event()函数是Linux内核USB子系统中的一个函数&#xff0c…

面试之ReentrantLock

一&#xff0c;ReentrantLock 1.ReentrantLock是什么&#xff1f; ReentrantLock实现了Lock接口&#xff0c;是一个可重入且独占式的锁&#xff0c;和Synchronized关键字类似&#xff0c;不过ReentrantLock更灵活&#xff0c;更强大&#xff0c;增加了轮询、超时、中断、公平锁…

侯捷 C++ part2 兼谈对象模型笔记——7 reference、const、new/delete

7 reference、const、new/delete 7.1 reference x 是整数&#xff0c;占4字节&#xff1b;p 是指针占4字节&#xff08;32位&#xff09;&#xff1b;r 代表x&#xff0c;那么r也是整数&#xff0c;占4字节 int x 0; int* p &x; // 地址和指针是互通的 int& r x;…

windows电脑简单实时tts语音播报wsay;python pyttsx3语言实时播报text-to-speech;微软edge-tts 音色自然离线不实时

1、wsay 参考&#xff1a; https://github.com/p-groarke/wsay 下载安装&#xff1a; https://github.com/p-groarke/wsay/releases/tag/v1.5.0 下载exe文件&#xff0c;并把加入环境变量就可 使用 # Say something. wsay "Hello there."wsay "你好"…

图书馆管理系统、学生管理系统、交通管理系统(C语言、数据结构、java、Javaweb)

图书馆管理系统作为一个经典的项目&#xff0c;在国家、学校、等每个地方或者作为期末作品都用的非常广泛&#xff1a; C语言程序设计&#xff1a;图书馆管理系统含说明文档。 大一时C综合设计&#xff0c;当时得了96。代码纯原创&#xff0c;可直接运行&#xff0c;包含详细注…

springboot多数据源配置,看这一篇就够了

springboot下多数据源配置实现 不管是两个mysql&#xff0c;还是一个mysql一个oracle&#xff0c;都是一样的操作 目录 springboot下多数据源配置实现配置application.yml文件数据源配置类创建mapper接口创建mapper的xml配置文件 你可能会遇到的问题 配置application.yml文件 …

无涯教程-Perl - study函数

描述 此功能需要花费额外的时间来研究EXPR,以改善在EXPR上执行的正则表达式的性能。如果省略EXPR,则使用$_。实际的速度增益可能非常小,具体取决于您希望搜索字符串的次数。 您一次只能学习一种表达式或标量。 语法 以下是此函数的简单语法- study EXPRstudy返回值 此函数…

Scala 如何调试隐式转换--隐式转换代码的显示展示

方法1 在需要隐式转换的地方&#xff0c;把需要的参数显示的写出。 略方法2&#xff0c;查看编译代码 在terminal中 利用 scalac -Xprint:typer xxx.scala方法打印添加了隐式值的代码示例。 对于复杂的工程来说&#xff0c;直接跑到terminal执行 scalac -Xprint:typer xxx.…

薅羊毛!我用这款AI工具,免费拿下12张漫画头像

今天l1m0_将为大家分享一款AI生图工具&#xff0c;并介绍如何通过Pixso AI&#xff0c;用自己的照片&#xff0c;免费一键生成AI漫画头像&#xff0c;一起来看看吧。 这里我用Pixso资源社区的一组用户头像资源&#xff0c;为大家演示&#xff0c;如何快速生成AI漫画头像。 首先…