模仿qsort实现一个通用的冒泡排序

目录

前言

模仿

排序整型数组

排序结构体数组

排序字符数组


前言

qsort在前面我们讲到底层逻辑是快速排序的方式,是不是可以发现有了qsort来进行排序的话,就更加的方便快捷,我们在使用的时候

一方面,代码量会大大的减少

另一方面,可以排序任意类型的数据

是不是发现了这函数的魅力呢?

那么今天我们也来当一个小小开发员来模仿qsort的功能实现一个通用的冒泡排序

我们先来简单的回顾一下冒泡排序:

#include<stdio.h>
void print_arr(int* arr, int sz)
{
	for (int i = 0; i < sz; i++)
		printf("%d ", *(arr + i));
}
void bubble_sort(int* arr, int sz)
{
	int i = 0;
	for (i = 0; i < sz - 1; i++)//趟数
	{
		int j = 0;
		for (j = 0; j < sz - 1 - i; j++)//每次比较的次数少一次
		{
			if (*(arr+j)>*(arr+j+1))
			{
				int temp = *(arr + j);
				*(arr + j) = *(arr + j + 1);
				*(arr + j + 1) = temp;
			}
		}
	}
}
int main()
{
	int arr[10] = { 2,4,1,6,9,5,3,8,0,7 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	//数组元素个数sz
	printf("排序前:\n");
	print_arr(arr, sz);
	bubble_sort(arr, sz);
	printf("\n排序前:\n");
	print_arr(arr, sz);
	return 0;
}

模仿

目前我们看来,冒泡排序似乎只可以排序整型,那么我们可不可以把它模拟像qsort那样可以排序任意类型的数据呢?

我们一起来试试,既然是模仿qsort那么和qsort应该是一样的函数参数

void imitate_bubble_sort(void* base, int count,int wideth,int (*cmp)(void*,void*))
//  base   ——排序数组的首元素地址
//  count  ——排序数组的元素个数
//  wideth ——排序数组一个元素的字节长度
//  cmp    ——函数指针(具体比较的函数的地址)

不同类型的数据在imitate_bubble_sort函数内部只是比较大小的代码不一样,所以就需要自己写比较的函数。

在比较的时候,因为不同类型的字节数不一样,我们可以根据传过去的width也就是排序数组一个元素的字节长度来访问不同大小的空间进而进行比较,如果满足条件再一个字节一个字节的进行交换,因为正好char类型是一个字节的,我们就可以把void*强制类型转换为char*

排序整型数组

具体代码如下:

#include<stdio.h>
void print_arr(int* arr, int sz)
{
	for (int i = 0; i < sz; i++)
		printf("%d ", *(arr + i));
}
int cmp_int(void* p1, void* p2)
{
	return *((int*)p1) - *((int*)p2);
	//根据具体的数据类型来写
}
void swap(char* p1, char* p2,int width)
{
	for (int i = 0; i < width; i++)
	{
		char temp = *(p1 + i);
		*(p1 + i) = *(p2 + i);
		*(p2 + i) = temp;
	}
	//一个字节一个字节进行交换
}
void imitate_bubble_sort(void* base, int count,int width,int (*cmp)(void*,void*))
//  base   ——排序数组的首元素地址
//  count  ——排序数组的元素个数
//  wideth ——排序数组一个元素的字节长度
//  cmp    ——函数指针(具体比较的函数的地址)
{
	int i = 0;
	for (i = 0; i < count - 1; i++)//趟数
	{
		int j = 0;
		for (j = 0; j < count - 1 - i; 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 main()
{
	int arr[10] = { 2,4,1,6,9,5,3,8,0,7 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	//数组元素个数sz
	printf("排序前:\n");
	print_arr(arr, sz);
	imitate_bubble_sort(arr, sz, sizeof(int), cmp_int);
	printf("\n排序后:\n");
	print_arr(arr, sz);
	return 0;
}

这里我们可以看到,它成功排序了整型,那么其它类型的数据可不可以呢?

排序结构体数组

我们来试试结构体类型的:

#include<stdio.h>
#include<string.h>//strcmp头文件
struct Student
{
	char name[20];
	int age;
};
void print_arr(struct Student* arr, int sz)
{
	for (int i = 0; i < sz; i++)
		printf("%s %d\n", (arr + i)->name, (arr + i)->age);
}
int cmp_student_by_name(void* p1, void* p2)
{
	return strcmp(((struct Student*)p1)->name, ((struct Student*)p2)->name);
}
void swap(char* p1, char* p2, int width)
{
	for (int i = 0; i < width; i++)
	{
		char temp = *(p1 + i);
		*(p1 + i) = *(p2 + i);
		*(p2 + i) = temp;
	}
}
void imitate_bubble_sort(void* base, int count, int width, int(*cmp)(void*, void*))
{
	int i = 0;
	for (i = 0; i < count - 1; i++)
	{
		int j = 0;
		for (j = 0; j < count - 1 - i; 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 main()
{
	struct Student stu_arr[3] = { {"lihua",24},{"wangdan",56},{"anna",18} };
	int sz = sizeof(stu_arr) / sizeof(stu_arr[0]);
	printf("排序前:\n");
	print_arr(stu_arr, sz);
	imitate_bubble_sort(stu_arr, sz, sizeof(stu_arr[0]), cmp_student_by_name);
	printf("\n排序后:\n");
	print_arr(stu_arr, sz);
	return 0;
}

排序字符数组

#include<stdio.h>
#include<string.h>
void print_arr(char* arr, int sz)
{
	for (int i = 0; i < sz; i++)
		printf("%-3c", arr[i]);
}
int cmp_char(void* p1, void* p2)
{
	return strcmp((char*)p1, (char*)p2);
}
void swap(char* p1, char* p2, int width)
{
	for (int i = 0; i < width; i++)
	{
		char temp = *(p1 + i);
		*(p1 + i) = *(p2 + i);
		*(p2 + i) = temp;
	}
}
void imitate_bubble_sort(void* base, int count, int width, int(*cmp)(void*, void*))
{
	int i = 0;
	for (i = 0; i < count - 1; i++)
	{
		int j = 0;
		for (j = 0; j < count - 1 - i; 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 main()
{
	char c[] = "dnjffskajkb";
	//c——字符数组
	int sz = sizeof(c) / sizeof(c[0]);
	printf("排序前:\n");
	print_arr(c, sz);
	imitate_bubble_sort(c, sz, sizeof(c[0]), cmp_char);
	printf("\n排序后:\n");
	print_arr(c, sz);
	return 0;
}

可以看见无论是结构体数组,还是字符数组,我们的代码得到了我们想要的结果!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

目标检测数据集 - 零售食品LOGO检测数据集下载「包含VOC、COCO、YOLO三种格式」

数据集介绍&#xff1a;零售食品 LOGO 检测数据集&#xff0c;真实零售食品 LOGO 高质量商品图片数据&#xff0c;数据集含常见零售食品 LOGO 图片&#xff0c;包括饮料类、酒类、调味品类、膨化饼干类、巧克力类、常见零食类等等。数据集类别丰富&#xff0c;标注标签包含 150…

DC/AC电源模块:为电动车充电基础设施提供高效能源转换

BOSHIDA DC/AC电源模块&#xff1a;为电动车充电基础设施提供高效能源转换 DC/AC电源模块是一种用于电动车充电基础设施的重要组件&#xff0c;它能够实现高效能源转换。在电动车的普及和推广过程中&#xff0c;DC/AC电源模块的重要性日益凸显。本文将从DC/AC电源模块的基本原…

Mybatis调用存储过程

在mysql数据库中创建一个存储过程 DELIMITER $$ CREATEPROCEDURE mybatisdemo1.pgetallusers(IN sid INT,IN eid INT)BEGINSELECT * FROM sb_users WHERE id>sid AND id<eid;END$$ DELIMITER ; 在Mapper接口里创建方法&#xff0c;和普通的查询数据方法没区别 在Mybati…

注册中心理论学习

注册中心介绍 注册中心&#xff08;也称为服务注册中心或服务发现服务&#xff09;是微服务架构中的一个关键组件&#xff0c;它负责服务的注册与发现。在微服务体系中&#xff0c;服务实例的数量和位置是动态变化的&#xff0c;注册中心提供了一个集中的地方来存储这些信息&a…

IDEA 设置主题、背景图片、背景颜色

一、设置主题 1、点击菜单 File -> Settings : 点击 Settings 菜单 2、点击 Editor -> Color Scheme -> Scheme, 小哈的 IDEA 版本号为 2022.2.3 , 官方默认提供了 4 种主题&#xff1a; Classic Light &#xff08;经典白&#xff09; ;Darcula &#xff08;暗黑主…

springboot景区寄存管理系统(源码+sql+论文报告)

针对传统人工行李寄存效率低和安全性不足等问题&#xff0c;设计并实现了一种由网页控制器组成的智能行李寄存系统。首先能够实现行李的寄存管理和行李柜管理以及记录查询和通知公告以及管理员等灵活控制菜单显示权限。经过研究和测试结果显示&#xff0c;该行李寄存系统实现了…

网页右键不能审查元素解决办法

网页右键不能审查元素解决办法 1.问题复现2.解决方法 1.问题复现 有的网站右键不能审查元素 这时是javascript 中的onselectstart"return false" 被禁止右键了。 2.解决方法 隐私和安全--->网络设置 网络设置--->javascript 然后回到不能审查元素的网页 …

数据结构01 栈及其相关问题讲解【C++实现】

栈是一种线性数据结构&#xff0c;栈的特征是数据的插入和删除只能通过一端来实现&#xff0c;这一端称为“栈顶”&#xff0c;相应的另一端称为“栈底”。 栈及其特点 用一个简单的例子来说&#xff0c;栈就像一个放乒乓球的圆筒&#xff0c;底部是封住的&#xff0c;如果你想…

远程连接路由器:方法大全与优缺点解析

远程连接路由器的方式主要有以下几种&#xff0c;以下是每种方式的详细说明及其优缺点&#xff1a; 使用Web浏览器登录 方法&#xff1a;通过配置路由器的远程管理功能&#xff0c;允许用户通过互联网浏览器访问路由器的管理界面。用户只需输入路由器的公网IP地址或域名&#…

exfat文件系统无法NFS导出的问题

最近项目中移植了exfat-linux驱动&#xff0c;但发现exfat格式的U盘无法用exportfs命令在NFS上导出。这篇文章记录了分析、解决方法。 一、问题现象 问题描述&#xff1a;exfat驱动更新后&#xff0c;exfat格式的U盘用exportfs命令NFS导出会报错 $ exportfs -o ro,fsid0,no_ro…

快消品经销商如何进行有效的团队激励?

很多经销商会面临员工工作不积极、吃大锅饭的现象&#xff0c;导致企业人力成本浪费严重&#xff0c;工作效率也得不到提升&#xff0c;因此经销商老板们必须进行一些绩效考核&#xff0c;然后开展一些有效的激励政策&#xff0c;这样通过提成激励来提高员工的积极性。 1、梳理…

SQL深度解析:掌握这些技巧,让你的数据库查询如虎添翼!

前言 随着大数据时代的来临&#xff0c;数据库的角色愈发重要。SQL作为使用最为广泛的数据查询语言&#xff0c;其深度解析与优化对于数据密集型应用来说至关重要。掌握高级SQL技巧不仅可以提升开发效率&#xff0c;还能显著提高数据查询的性能和灵活性。本文将探讨一些关键的S…

QT信号与槽/窗口组件优化/使用QT制作QQ登录界面

使用手动连接&#xff0c;将登录框中的取消按钮使用第二中连接方式&#xff0c;右击转到槽&#xff0c;在该槽函数中&#xff0c;调用关闭函数 将登录按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断u界面上输入的账号是否为"admin"&#xff0c;…

表面声波滤波器——SAW 基本介绍(1)

声表面波特点与应用 声表面波&#xff0c;也称为表面声波&#xff08;surface acoustic wave&#xff09;&#xff0c;是指在弹性体的自由表面上产生并沿着表面或界面传播的各种模式的波&#xff0c;包括瑞利波(Rayleighwave)&#xff0c;勒夫波(Lovewave)等。 具有以下特点:…

mediamtx流媒体服务器测试

MediaMTX简介 在web页面中直接播放rtsp视频流&#xff0c;重点推荐&#xff1a;mediamtx&#xff0c;不仅仅是rtsp-CSDN博客 mediamtx github MediaMTX(以前的rtsp-simple-server)是一个现成的和零依赖的实时媒体服务器和媒体代理&#xff0c;允许发布&#xff0c;读取&…

MySQL JDBC驱动包引入有版本要求吗

提示&#xff1a;有关数据库的任何操作&#xff0c;请事先都做好备份&#xff0c;一定不会错的&#xff1b; 文章目录 前言一、com.mysql.jdbc.Driver和com.mysql.cj.jdbc.Driver如何选择&#xff1f;1、概念2、引入驱动3、总结 前言 新老项目的交替中&#xff0c;如果你使用的…

天阳科技集团北京卡洛其项目管理专家李先林受邀为第十三届中国PMO大会演讲嘉宾

全国PMO专业人士年度盛会 天阳科技集团北京卡洛其项目管理专家李先林先生受邀为PMO评论主办的2024第十三届中国PMO大会演讲嘉宾&#xff0c;演讲议题为“应用软件项目管理标准化实践探讨”。大会将于6月29-30日在北京举办&#xff0c;敬请关注&#xff01; 议题简要&#xff1…

基于ChatGPT的大型语言模型试用心得

近年来&#xff0c;ChatGPT这样的大型语言模型&#xff0c;它如同一颗冉冉升起的新星&#xff0c;迅速在商业、教育、娱乐等多个领域照亮了创新的天空&#xff0c;极大地革新了我们的工作与日常生活。 最近我发现一些国内用户也能自由访问的中文ChatGPT APP。这个平台不仅提供…

Zabbix Centos8 安装笔记

Zabbix 安装笔记 安装环境 Centos 8 正常发行版 安装版本 Zabbix 7 (LTS) 安装步骤 1、关闭防火墙 systemctl stop firewalld && systemctl disable firewalld && setenforce 0 && sed -i s/SELINUXenforcing/SELINUXdisabled/g /etc/selinux/c…

【笔记】复制Edge的网址粘贴后自动变成中文标题超链接

问题 1、从edge复制的网址粘贴直接显示网页内容名称而不是网址url。 2、复制任何网址粘贴到CSDN里面粘贴时直接转换成标题超链接&#xff08;很讨厌的功能习惯&#xff09;。 而如上两种问题不是互相影响的&#xff0c;就算设置了Edge的粘贴方式&#xff0c;复制到CSDN的文章…