用冒泡排序实现快速排序(qsort函数),指针进阶实例

news2025/1/13 3:37:19

目录

 

1、qsort函数是什么

2、冒泡排序实现指针进阶

2.1 主函数

2.2 功能函数声明​编辑

2.3 my_qsort函数介绍

2.4 Swap函数

总结


 

1、qsort函数是什么

        qsort函数是c语言自带的函数,其功能是实现快速排序。我们来看一下他的参数和返回值:b1da2fd3888c439a9030cf4b1034276a.png

        以上就是qsort的参数和返回值,可以看到,其返回值是void也就是没有返回值;而参数方面,包括:void* base 这是要排序的数据的起始位置的指针、 size_t num 待排序的数据元素个数、 size_y width 待排序数据元素的大小(单位是字节)、 int(* cmp)(const void* e1,const void* e2) 函数指针变量,其指向一个返回值为int类型,参数为两个void*的指针e1和e2,他们分别指向要排序数据的第一个元素和第二个元素。

        看一个用qsort实现的排序:ac98a28ccd4c4a4eaaebf0f978f44236.png

        我们需要自己定义一个cmp函数,里面设计一个比较函数,e1 和 e2 指向数据的前两个元素,如果设计为:*e1大于*e2时返回正值;*e1等于*e2时返回0;*e1小于*e2时返回负值时,qsort就会实现对数据的升序排列,反之,qsort就会实现降序排列。因此,我们发现,qsort实现的功能其实取决于我们如何去设计cmp函数。此外,qsort可以比较不仅限于整型数据的大小,还可以比较字符串等等各种类型的大小,其规则和整型相同,都是取决于如何去设计cmp函数。

        好了,讲到这我们大致了解了qsort函数,现在,我们将用冒泡排序去实现qsort的功能。这样的练习有助于我们更好地了解和运用指针,实现我们对c语言的进阶。

2、冒泡排序实现快速排序

        先看看最终代码:

#include <stdio.h>

void my_qsort(void* base, int num, int width, int (*cmp)(const void* e1, const void* e2));
void Swap(char* e1, char* e2, int width);
int cmp(const void* e1, const void* e2);

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	my_qsort(arr,sz,sizeof(int),cmp);
	int i = 0;
	for (i = 0;i < sz;i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

void my_qsort(void* base, int num, int width, int (*cmp)(const void* e1, const void* e2))
{
	int i = 0;
	for (i = 0;i <num-1;i++)
	{
		int flag = 1;
		int j = 0;
		for (j = 0;j < num - 1 - i;j++)
		{
			if (cmp((char*)base + width * j, (char*)base + width * (j + 1)) < 0)
			{
				//交换
				Swap((char*)base + width * j, (char*)base + width * (j + 1),width);
			}
			
		}
	}
}

void Swap(char* e1, char* e2, int width)
{
	int i = 0;
	int c = 0;
	for (i = 0;i < width;i++)
	{
		c = *(e1 + i);
		*(e1 + i) = *(e2 + i);
		*(e2 + i) = c;
	}
}

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

效果:

edc583e62d9441fe9f1c97eedb63cf4d.png

可见确实模拟出了qsort的效果。

一步步分析:

2.1 主函数

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	my_qsort(arr,sz,sizeof(int),cmp);
	int i = 0;
	for (i = 0;i < sz;i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

        主函数主要是arr数组的定义,求其长度sz,引用my_qsort函数和打印排序后的函数。没有需要重点讲的。

        接下来介绍所运用到的功能函数:

2.2 功能函数声明3a1eae1069d446b294829609d3db822f.png

        这里包括了三个函数,my_qsort就是用冒泡排序模拟实现qsort的函数,Swap函数是用来交换e1和e2的函数,cmp就是正常qsort中我们需要自己设定的函数,可以通过改变cmp的内容实现不同效果的排序。其中cmp在上面已经介绍过了所以下面我只重点介绍my_qsort函数和Swap函数。

2.3 my_qsort函数介绍

d97290f07b964adfa717f572dfebfc0d.png

        首先要明白,这个函数的主要思想其实是一个冒泡排序。只不过在正常冒泡排序的交换过程我们用了Swap函数代替。

        重点来了,来看看其中这两行的代码:310df004c47141be8b8dd361306e2b1c.png

        这里我们将原本void类型的代码转化为了cahr*,这是因为,我们模拟的qsort是一个可以对任何数据进行排序的函数,不仅限于int类型,所以,我们要想一个办法能够用指针去指向任意大小的数据,我们考虑的就是char*类型,因为我们传参的时候将元素的大小width传了过来,这样,我们定义了char*类型的指针(1字节),只需要用i*width就可以指向后i个数据;反之,如果不用char*类型的话,其他类型的指针步长本身都不为1字节,,这样加上i无法确定指针指向了哪个数据。

        下面,来讲解一下Swap函数:

2.4 Swap函数

928c87de5dd048328b0d0f37f608fb98.png

        Swap函数实现的是大小为width的两个元素的互换,由于我们指针e1和e2为char类型,所以,想要完全互换的话,需要对指针后width个内容都进行互换,因此我们写了如此一个循环进行互换。

总结

        以上,就是用冒泡排序实现qsort函数的模拟了,它不仅可以对整型数据进行排序,还可以对任意类型数据进行排序,其中运用到了函数指针,也要求编程者对函数有一定深刻的理解。了解好原理,自己动手去完成这样一个函数模拟,我相信,你对指针的的理解会上升一个台阶。

 

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

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

相关文章

代码随想录算法训练营DAY21 | 二叉树 (9)

一、LeetCode 669 修建二叉搜索树 题目链接&#xff1a;669.修建二叉搜索树https://leetcode.cn/problems/trim-a-binary-search-tree/description/ 思路&#xff1a;递归三部曲-定参数、返回值-定终止条件-定单层递归逻辑 class Solution {public TreeNode trimBST(TreeNode …

深度学习基础——卷积神经网络(一)

卷积操作与自定义算子开发 卷积是卷积神经网络中的基本操作&#xff0c;对于图像的特征提取有着关键的作用&#xff0c;本文首先介绍卷积的基本原理与作用&#xff0c;然后通过编写程序实现卷积操作&#xff0c;并展示了均值、高斯与sobel等几种经典卷积核的卷积效果&#xff…

HTML-介绍-MDN文档学习笔记

HTML-介绍 查看更多学习笔记&#xff1a;GitHub&#xff1a;LoveEmiliaForever MDN中文官网 HTML-简介 MDN 文档引用&#xff1a; 就其核心而言&#xff0c;HTML 是一种相当简单的、由不同元素组成的标记语言&#xff0c;它可以被应用于文本片段&#xff0c;使文本在文档中具…

Security6.2 中的SpEL 表达式应用(权限注解使用)

最近学习若依框架&#xff0c;里面的权限注解涉及到了SpEL表达式 PreAuthorize("ss.hasPermi(system:user:list)")&#xff0c;若依项目中用的是自己写的方法进行权限处理&#xff0c; 也可以只用security 来实现权限逻辑代码&#xff0c;下面写如何用security 实现。…

[计算机网络]---UDP协议

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、端口号…

HarmonyOS - 实现多设备协同开发实战教程~

前言 现在随着个人设备越来越多&#xff0c;越来越需要多个设备之间相互感知和连接&#xff0c;设备和设备之间可以相互联动&#xff0c;形成互联互通的场景&#xff0c;而搭载HarmonyOS的设备恰好可以满足这一点 。下面通过开发一个HarmonyOS的多端分布式表白应用来实现设备之…

STM32_ESP8266 连接阿里云 操作图解

一、烧录MQTT固件 ESP8266出厂时&#xff0c;默认是&#xff1a;AT固件。连接阿里云需要&#xff1a;MQTT固件。 因此&#xff0c;我们需要给8266重新烧录 MQTT固件。 针对“魔女开发板&#xff0c;ESP8266模块烧录MQTT固件&#xff0c;图解教程如下&#xff1a; ESP8266 烧录 …

代码随想录算法训练营|二叉树总结

二叉树的定义&#xff1a; struct TreeNode {int val;TreeNode* left;TreeNode* right;TreeNode():val(0),left(nullptr),right(nullptr){}TreeNode(int val):val(val),left(nullptr),right(nullptr){}TreeNode(int val,TreeNode* left,TreeNode* right):val(val),left(left),…

网工内推 | 证券公司急招网工,base上海,年薪50W

01 广发证券 招聘岗位&#xff1a;网络工程师 任职要求&#xff1a; 1、懂基础建设网络&#xff0c;虚拟化&#xff0c;或者服务器中任意一个都可以&#xff08;需资深&#xff09;2、985/211本硕 3、年龄最好35以下 薪资待遇&#xff1a; 1、工作时间9:00-17:00 2、根据资历…

思腾合力邀您共赴第二届世界元宇宙大会

由中国仿真学会、中国指挥与控制学会和北京理工大学共同主办&#xff0c;上海市嘉定区安亭镇人民政府和中国仿真学会元宇宙专业委员会承办的第二届世界元宇宙大会大会以“虚实相生、产业赋能”为主题&#xff0c;聚焦元宇宙关键技术发展的共性问题&#xff0c;交流元宇宙技术产…

Window系统GPT-SoVITS配置安装

GPT-SoVITS配置安装 GPT-SoVITS配置Python下载以及安装源文件安装依赖 运行整理在安装配置环境时遇到的报错总结 GPT-SoVITS配置 作者链接 Python下载以及安装 版本这里根据教程的版本走即可&#xff0c;这里不会安装python或者不会配置环境的参考我之前的文章 Python 3.9,…

C# GTS四轴运动控制器实例(固高科技步进电机不带编码器)

注&#xff1a;由于电机不带编码器&#xff0c;无法做home和当前位置信息读取&#xff01; 功能&#xff1a; 三个轴的点位运动&#xff1a;前进后退&#xff0c;并分别显示每个轴的移动脉冲数(可以换算为距离)&#xff01; 开发环境&#xff1a;VS2017 硬件设备&#xff1a;固…

编程笔记 Golang基础 007 第一个程序:hello world 使用Goland

编程笔记 Golang基础 007 第一个程序&#xff1a;hello world 使用Goland 步骤1&#xff1a;启动GoLand并创建新项目步骤2&#xff1a;创建主包和主函数步骤3&#xff1a;运行程序小结 开始在Goland环境中编程go语言代码啦。 步骤1&#xff1a;启动GoLand并创建新项目 打开GoL…

[word] word中图片衬于文字下方无法显示 #媒体#微信

word中图片衬于文字下方无法显示 1、如图&#xff0c;图片“衬于文字下方”&#xff0c;文字下方的图象看不见 2、光标这位到图片上这段文字中&#xff0c;点击“格式”&#xff0d;“边框和底纹”&#xff0c;切换到“底纹”选项卡。可发现这两段文字底纹被设置成“白色”了 …

【数学建模入门】

数学建模入门 数学建模需要的学科知识怎么学习数学模型如何读好一篇优秀论文数学建模赛题常见类别数学建模常见问题数学建模组队和分工数学建模准备工作 数学建模需要的学科知识 怎么学习数学模型 &#x1f4a6;推荐阅读书籍&#xff1a; 《数学建模算法与应用》&#xff0c;…

OpenGL学习——17.模型

前情提要&#xff1a;本文代码源自Github上的学习文档“LearnOpenGL”&#xff0c;我仅在源码的基础上加上中文注释。本文章不以该学习文档做任何商业盈利活动&#xff0c;一切著作权归原作者所有&#xff0c;本文仅供学习交流&#xff0c;如有侵权&#xff0c;请联系我删除。L…

FlinkCDC详解

1、FlinkCDC是什么 1.1 CDC是什么 CDC是Chanage Data Capture&#xff08;数据变更捕获&#xff09;的简称。其核心原理就是监测并捕获数据库的变动&#xff08;例如增删改&#xff09;&#xff0c;将这些变更按照发生顺序捕获&#xff0c;将捕获到的数据&#xff0c;写入数据…

Vue | (二)Vue组件化编程 | 尚硅谷Vue2.0+Vue3.0全套教程

文章目录 &#x1f4da;模块与组件、模块化与组件化&#x1f4da;非单文件组件&#x1f407;基本使用&#x1f407;关于组件的几个注意点&#x1f407;组件的嵌套 &#x1f4da;单文件组件&#x1f407;一个.vue 文件的组成&#x1f407;实例 学习链接&#xff1a;尚硅谷Vue2.0…

多线程、分布式运行用例

python多线程 threading模块 多线程实例 # -*- coding: utf-8 -*- # Time : 2024/2/7 15:50 # Author : 居里夫人吃橘子 # File : class01.py # Software: PyCharm import threading from time import sleepdef run(name):print(name 该起床了)sleep(2)print(name …

EXCEL使用VBA一键批量转换成PDF

EXCEL使用VBA一键批量转换成PDF 上图是给定转换路径 Sub 按钮1_Click() Dim a(1 To 1000) As String Dim a2 As String Dim myfile As String Dim wb As Workbook a2 Trim(Range("a2"))myfile Dir(a2 & "\" & "*.xls")k 0Do While m…