用代码生撸qsort函数来实现冒泡排序

news2024/11/27 10:43:37

作者主页:paper jie的博客_CSDN博客-C语言,算法详解领域博主

本文作者:大家好,我是paper jie,感谢你阅读本文,欢迎一建三连哦。

本文录入于《C语言》专栏,本专栏是针对于大学生,编程小白精心打造的。笔者用重金(时间和精力)打造,将C语言基础知识一网打尽,希望可以帮到读者们哦。

其他专栏:《系统解析C语言》《算法详解》《C语言-语法篇》

内容分享:本期将用代码生撸C语言中的qsort函数实现冒泡排序,各位看官姥爷快搬好小板凳坐好叭。

    -------- 不要998,不要98,只要一键三连,三连买不了吃亏,买不了上当

前言

在之前的文章中我们讲了简单冒泡排序的实现(不熟悉可以去回顾回顾http://t.csdn.cn/OI3hN),冒泡排序就是多种排序中的一种简单排序。核心思想就是相邻的元素两两比较,每一对都要比较,符合要求就交换位置,不断重复,直到没有元素需要比较。接下来我们将会了解C语言的库函数qsort,它也可以实现冒泡排序,而且比我们之前写的完善多了,可以适用于不同类型。

冒泡排序的实现

冒泡排序的核心思想是让相邻的元素两两比较,每一对都要比较,符合要求就交换位置,不断重复,直到没有元素需要比较

算法思想的实现:假设数组内有n个数随机排放。1.在数组初始状态下, 我们将整个数组设为排序范围,范围为数组下标为0-n-1的数。 2.从下标为0的数开始,两两相邻的数比较,如果前一个数大于后一个数,则进行交换。交换后再和后一个数进行比较,一直比较到最后一个数,这样最大的数就被排到到最后了。 3.前面为第一趟排序,我们需要进行n-1趟排序,假设第一次排序标记为0,标记数为i,每过一趟i+1,那么每次排序需要两两比较的次数为 n-1-i。4排序到没有元素可以排序后则排序完成。

下面的代码就是我们自己实现的冒泡排序,我们通过用i控制它的趟数,j控制它每一趟交换多少组来实现了升序。但是这里还有一个很大的问题:它只能对int类型的数据进行排序,换成其他的就不行了。那有没有什么可以让它可以用于不同的类型数据呢? 

#include <stdio.h>
void bubble_sort(int* arr, int sz)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < sz - 1; i++)
	{
		for (j = 0; j < sz - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}
int main()
{
	int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	bubble_sort(arr, sz);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

qsort函数

qsort函数的定义

qsort函数是C语言库中的一个函数,它的功能就是对不同的数据类型进行降序或者升序排序,就是相当于冒泡排序。不了解它也没关系,我们可以去 qsort - C++ Reference (cplusplus.com) 上查询qsort函数。

我们通过文档可以发现:qsort有4个参数,第一个参数就是数组的首地址,第二参数是数组的元素,第三个参数是元素的大小,第四个参数是一个函数指针,它是用来比较待排序中的两个元素的,它的返回值就是这两个元素相减,>0的话,qsort函数就交换两个元素。这个函数指针指向的函数需要使用者自己设计,因为设计者不知道你要排序的是什么类型的。需要引用头文件是stdlib.h。

qsort函数的使用

这里我们就以int数组,和结构体数组为例:

整型数组为例:

#include <stdio.h>
#include <stdlib.h>
//整型数组 - 例
int  compar_int(const void* e1, const void* e2)
{
	return *(int*)e1 - *(int*)e2;
}

int main()
{
	//数组
	int arr[10] = { 10,9,8,7,6,5,4,3,2,1 };
	//元素个数
	int sz = sizeof(arr) / sizeof(arr[0]);
	//传参
	qsort(arr, sz, sizeof(arr[0]), compar_int);
	//打印
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

结构体数组为例:

#include <stdio.h>
#include <stdlib.h>
//整型数组 - 例
struct Stu
{
	char name[20];
	int age;
};

int  compar_int(const void* e1, const void* e2)
{
	return ((struct Stu*)e1)->age - ((struct Stu*)e2) -> age;
}

int main()
{
	//数组
	struct Stu s[] = { {"zhngsan",34},{"lishi",25},{"wangwu", 20}};
	//元素个数
	int sz = sizeof(s) / sizeof(s[0]);
	//传参
	qsort(s, sz, sizeof(s[0]), compar_int);
}

qsort函数的模拟实现

这里还是以int类型数组举例:

#include <stdio.h>

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

//交换函数
//通过char类型加上width来跳过元素
//char+width(类型的大小)刚好是一个类型的大小
void swap(char *e1, char *e2, int width)
{
	int i = 0;
	
	for (i = 0; i < width; i++)
	{
		//每一次循环交换一个字节控制的空间的内容
		//循环完width次彻底交换两个元素
		char tmp = *e1;
		*e1 = *e2;
		*e2 = tmp;
		e1++;
		e2++;
	}
}
//模拟函数
void bublle_sort(void* base, int sz, int width, int (*compar)(const void*, const void*))
{
	int i = 0;
	int j = 0;
	for (i = 0; i < sz - 1; i++)
	{
		for (j = 0; j < sz - 1 - i; j++)
		{
			//如果compar函数大于0 就交换
			if (compar((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] = { 10,9,8,7,6,5,4,3,2,1 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	//模拟qsort函数
	bublle_sort(arr, sz, sizeof(arr[0]), compar_int);
		for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
	return 0;
}

总结

这就是qsort函数的使用和模拟,我们通过使用和模拟发现,qsort函数它非常的巧妙,不由的让我们感叹写出这些代码的人脑子怎么长的,不过我相信只要我们一直学习下去,总有一天我们也有写出这种代码的可能性,与君共勉!

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

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

相关文章

Windows 系统彻底卸载 SQL Server 通用方法

Windows 系统彻底卸载 SQL Server 通用方法 无论什么时候&#xff0c;SQL Server 的安装和卸载都是一件让我们头疼的事情。因为不管是 SQL Server 还是 MySQL 的数据库&#xff0c;当我们在使用数据库时因为未知原因出现问题&#xff0c;想要卸载重装时&#xff0c;如果数据库…

Jetson Xavier NX 备份与烧录固态系统

目录 1 需要的硬件 2 需要安装在ubuntu上的软件 2.1 安装gparted 2.2 安装nvidia官方烧录包 2.2.1 下载 2.2.2 配置 3 备份系统 4 烧入系统 1 需要的硬件 像是 nx&#xff0c;nx附带的固态硬盘&#xff0c;显示器 这些就赘述了 一个ubuntu实体机(虚拟机听说…

ansible-roles模块

roles用于层次性&#xff0c;结构化地组织playbook&#xff0c;roles能够根据层次型结构自动装载变量文件&#xff0c;tasks以及handlers等。要使用只要载playbook中使用include指令引入即可。 &#xff08;roles就是通过分别将变量&#xff0c;文件&#xff0c;任务&#xff…

u盘中毒文件夹数据丢失怎么恢复?这里有4个恢复方案

您是否曾经遇到过U盘中毒的情况&#xff1f;连累到文件夹内的数据文件消失了&#xff0c;如果丢失的是重要数据&#xff0c;这或许会对我们工作或学习带来了极大的困扰。为了解决您的困扰&#xff0c;下面将根据不同情况给予不同的U盘中毒数据恢复方案&#xff0c;帮助您尽快找…

小红书各行业流量分析:普通人怎么有效使用小红书?

随着互联网的发展&#xff0c;越来越多的人开始利用自媒体平台赚钱。小红书是近年来兴起的一种新型自媒体平台&#xff0c;也是国内最大的海外购物分享平台之一。随着小红书用户的不断增加&#xff0c;小红书的流量趋势也在发生着变化。那么&#xff0c;在各行业的流量趋势中&a…

驱动开发:文件微过滤驱动入门

MiniFilter 微过滤驱动是相对于SFilter传统过滤驱动而言的&#xff0c;传统文件过滤驱动相对来说较为复杂&#xff0c;且接口不清晰并不符合快速开发的需求&#xff0c;为了解决复杂的开发问题&#xff0c;微过滤驱动就此诞生&#xff0c;微过滤驱动在编写时更简单&#xff0c;…

XV-440-10TVB-1-50伊顿触摸屏EATON

​ XV-440-10TVB-1-50伊顿触摸屏EATON XV-440-10TVB-1-50伊顿触摸屏EATON ESD与dcs是完全分离的。DCS主要用于过程工业参数指标的动态控制。在正常情况下&#xff0c;DCS动态监控着生产过程的连续运行&#xff0c;保证能生产出符合要求的优良产品。而ESD则是对于一些关键的工艺…

python获取某博热搜数据并保存成Excel

python获取某博&#x1f9e3;热搜数据 一、获取目标、准备工作二、开始编码 一、获取目标、准备工作 1、获取目标&#xff1a; 本次获取教程目标&#xff1a;某博&#x1f9e3;热搜 2、准备工作 环境python3.xrequestspandas requests跟pandas为本次教程所需的库&#xff0c…

AM@空间曲面@平面@面面位置关系@点面距离

文章目录 曲面曲线平面点法式方程不共线的3点确定一个平面方程同解平面方程的一般式特别情形与坐标轴平行的平面与坐标轴垂直与坐标面平行的平面ABC0例 截距式两平面的夹角&#x1f47a;两平面的位置关系垂直关系平行关系例 点到平面的距离小结例 曲面 空间解析几何中"曲…

潜伏顶升AMR ∣解决方案背后——不断进化的市场和客户需求

潜伏顶升式AMR是通过潜入料架底部&#xff0c;利用升降机构提升料架&#xff0c;实现物料的输送;可支持货架、料车、笼车等多种载具,多用于物料架、物料车的转运。有效降低人力资源成本&#xff0c;减轻人工劳动强度。 作为移动机器人&#xff08;AMR/AGV&#xff09;近几年发展…

SpringBoot中集成Redis

目标 在原有SpringBoot项目中&#xff0c;集成Redis&#xff0c;并实现Dao层&#xff0c;Service层&#xff0c;Controller层。 pom.xml <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</…

大数据云计算运维之Nginx反向代理与负载均衡

Nginx 简介 一、Nginx概述 1.1 概述 Nginx&#xff08;“engine x”&#xff09;是一个高性能的 HTTP /反向代理的服务器及电子邮件&#xff08;IMAP/POP3)代理服务器。 官方测试nginx能够支撑5万并发&#xff0c;并且cpu&#xff0c;内存等资源消耗却非常低&#xff0c;运…

合并reducer

reducer工程化第一步&#xff1a;合并 各个模块下reducer的模板: 1.符是代表直接从src下面进行寻找 2.定义初始状态 3.深拷贝状态 4.进行行为判断 votereducer这么写&#xff1f; 合并reducer 导出总的reducer 模块化开发后往事件池放的更新方法&#xff0c;在disptch的时候…

交换机新设备版本升级(超详细!快进来学习!)

本文主要讲述了华三新上架交换机机设备升级全过程&#xff01;同理&#xff0c;其他的交换机设备进行升级也是同样的思路&#xff01; 升级流程 1、使用console线以及网线将电脑和交换机进行连接&#xff08;console口和网口&#xff09;; 2、打开以太网卡&#xff0c;“控制面…

25k字图文解读YOLOv8及实例分割(附python代码)

学习使用 未经详细专业审核 目录 0.引言1.概述1.1 Backbone1.2 Head1.3 Loss1.4 Train 2.模型结构2.1 Backbone和Neck的具体变化2.2 Head的具体变化 3.Loss计算3.1 正负样本分配策略3.2 Loss计算 4.训练数据增强5.训练策略6.模型推理过程7.网络模型解析7.1 卷积神经单元&#x…

软件设计模式之原型模式

一.定义 原型模式(Prototype Pattern)的简单程度仅次于单例模式和迭代器模式。正是由于简单&#xff0c;使用的场景才非常地多&#xff0c;其定义如下: Specify the kinds of objects to create using a prototypical instance, and create new objects by copyingthis protot…

基础设施SIG月度动态:ABS新增ISO、VHD镜像构建,自动热补丁制作流程正式上线

基础设施 SIG&#xff08;OpenAnolis Infra SIG&#xff09;目标&#xff1a;负责 OpenAnolis 社区基础设施工程平台的建设&#xff0c;包括官网、Bugzilla、Maillist、ABS、ANAS、CI 门禁以及社区 DevOps 相关的研发工程系统。 01 SIG 整体进展 1、龙蜥社区官网与 CSDN dev…

smigroup LAFERT 伺服电机 B7108P-03177

​ smigroup LAFERT 伺服电机 B7108P-03177 smigroup LAFERT 伺服电机 B7108P-03177 从系统的可扩展性和兼容性的方面来说&#xff1a; 市场上控制类产品繁多&#xff0c;无论DCS还是PLC&#xff0c;均有很多厂商在生产和销售。对于PLC系统来说&#xff0c;一般没有或很少有扩…

如何与领导团队沟通并赢得他们的支持以推动企业的敏捷转型进程?

在与领导团队沟通并赢得他们对敏捷转型的支持时&#xff0c;重要的是要从战略上有效地处理这种情况。建议采取的一些步骤&#xff1a; 了解他们的观点&#xff1a;在开始任何沟通之前&#xff0c;尝试了解领导团队对敏捷转型的担忧和保留意见。可以帮助调整方法并解决具体问题。…

2023年5月信息系统项目管理师试题及答案解析

请点击↑关注、收藏&#xff0c;本博客免费为你获取精彩知识分享&#xff01;有惊喜哟&#xff01;&#xff01; 1.“新型基础设施”主要包括信息技术设施&#xff0c;融合基础设施和创新基础设施三个方面&#xff0c;其中信息基础设施包括___1___。 ①通信基础设施 ②智能交…