模拟实现qsort函数(采用冒泡排序的方式)

这篇具有很好参考价值的文章主要介绍了模拟实现qsort函数(采用冒泡排序的方式)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言:

之前我在C语言:指针详解【进阶】后篇中提到了qsort函数,qsort函数作为一个库函数,在我们日常的代码编写中可能会用到,在上面提到的文章中我们也进行使用了这个函数,大家也了解了一些这个函数的使用方法,但我们作为学习者,我们不仅要会用,还要知道这个qsort函数的原理,更要自己能够模拟实现一个qsort函数来,这样才能对这个函数有更深刻的理解。

这里我们再次回顾一下qsort函数的用法,我们不清楚的可以打开cplusplus.com的网站搜索一下qsort函数 进行查看
引文原版:
模拟实现qsort函数(采用冒泡排序的方式)


中文网页翻译:(尽量看原版更准确哦)
模拟实现qsort函数(采用冒泡排序的方式)
从引文来看,qsort函数是一个可以排列任意类型数据的函数。
我们先从这个函数的参数来看:
模拟实现qsort函数(采用冒泡排序的方式)

这个函数一共有四个参数,一个void*类型的指针,两个size_t类型的整型,一个返回类型为int 、函数参数为两个void*类型的指针的函数指针。

这代表着在使用qsort函数时,我们需要知道要排序的第一个元素的地址,要排序元素的个数,每个元素的大小,以及一个能比较两个元素的大小的函数。

注:

size_t 是无符号整型

这里我们先简单使用一下这个函数:(记得引用头文件)

#include <stdio.h>
#include <stdlib.h>
int cmp_int(const int* p1, const int* p2)
{
	return *p1 - *p2;
}
int main()
{
	int arr[10] = { 7,6,1,2,8,9,3,5,0,4 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(int), cmp_int);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

模拟实现qsort函数(采用冒泡排序的方式)


这个排序的原理可以类比一下一个简单的排序方法:冒泡排序。它与冒泡排序的底层排序思想可以看作是大致相似的。
这里简单实现一下冒泡排序:

#include <stdio.h>
void bubble_sort(int arr[], int sz)
{
	for (int i = 0; i < sz; i++)
	{
		int flag = 1;
		for (int j = 0; j < sz - i - 1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
				flag = 0;
			}
		}
		//当flag等于1时,说明这一趟排序未发生交换,说明顺序已经排好了
		if (flag)
			break;
	}
}
int main()
{
	int arr[10] = { 7,6,1,2,8,9,3,5,0,4 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	bubble_sort(arr, sz);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

模拟实现qsort函数(采用冒泡排序的方式)

注:
由于qsort函数的真正底层排序思想是:快速排序的方法,这里我就先用冒泡排序来模拟实现一下这个函数,后面有机会,我也会把快速排序的模拟实现讲解出来的。


实现思路:

对于qsort函数的模拟实现来说,最难的部分是如何实现任意类型数据的排序,我们之前对于确定的数据进行排序时,往往可以用对应的方法进行比较两元素并进行交换来排序,但qsort函数在使用时,设计这个函数的人在编写这个函数时并不确定这个函数将来要排列什么类型的数据,所以他在设计函数参数时不能限定函数传参传过来的数据类型,所以要把第一个函数参数设计成一个void*类型的指针
现在函数已经把要排序的第一个元素的地址传过来了,那接下来还要传要排序的元素个数,来确定排序的次数。
同时,由于第一个参数是void*类型的,我们还要确定要排序元素的字节数,所以还要传每个元素的大小
最后,由于不同类型的元素的比较形式不同,我们需要用不同的方法来比较传过来的数据,但是函数设计并不能预见所有的排序情况,这就需要使用者在使用qsort函数时,自己编写一个能比较两个要传元素的大小的函数,再把这个函数的地址穿过来就行了


看到这里,我们大致清楚了qsort函数的设计思路,这里我们就简单的编写一个my_qsort函数来模拟实现一下这个函数吧。

模拟实现qsort函数(采用冒泡排序的方式)

这里我们对函数内容编写时要注意,我们传过来的元素数据时各种各样的,但我们的函数参数的接受时是void*的参数,我们如何知道我们访问几个字节就找到我们要排序的一个元素呢?
这时就需要使用到我们的第三个参数了,第三个参数接收的就是我们要排序的一个元素的大小(字节),我们只需要一次访问size个字节的数据就可以找到每个要排序的元素了,这时需要将base强制类型转换成char*类型的指针再乘以size就是完整的一个要排序的元素数据了。

模拟实现qsort函数(采用冒泡排序的方式)

现在我们需要进行相邻两个元素的比较,这里的比较就是使用者要传过来的函数指针,这里的比较函数要使用者自己编写

注意:设计的比较函数要和库里给定的该比较函数模板格式要一致。

同时,相邻元素比较完后,如果不符合顺序就需要交换相邻两元素了,这里我们再设计一个my_swap函数来进行交换:
对于要交换任意类型的数据,数据指针的接受也要设计成void*类型的,同时要传递数据的字节大小来找到整个数据,然后在函数内部用一层for循环来交换每个字节的数据就可以了。
代码实现:

void my_swap(void* p1, void* p2, size_t size)
{
	size_t i = 0;
	for (i = 0; i < size; i++)
	{
		char tmp = *((char*)p1 + i);
		*((char*)p1 + i) = *((char*)p2 + i);
		*((char*)p2 + i) = tmp;
	}
}

这样我们的my_qsort函数就设计完成了。


代码实现:

void my_swap(void* p1, void* p2, size_t size)
{
	size_t i = 0;
	for (i = 0; i < size; i++)
	{
		char tmp = *((char*)p1 + i);
		*((char*)p1 + i) = *((char*)p2 + i);
		*((char*)p2 + i) = tmp;
	}
}
void my_qsort(void* base, size_t num, size_t size, int (*cmp)(const void*, const void*))
{
	size_t i = 0;
	size_t j = 0;
	for (i = 0; i < num - 1; i++)
	{
		for (j = 0; j < num - i - 1; j++)
		{
			if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0)
			{
				my_swap((char*)base + j * size, (char*)base + (j + 1) * size, size);
			}
		}
	}
}

这里就举两个示例来感受一下:
示例一:(排列整型数据)

#include <stdio.h>
int cmp_int(const int* p1, const int* p2)//比较函数
{
	return *p1 - *p2;
}
void my_swap(void* p1, void* p2, size_t size)
{
	size_t i = 0;
	for (i = 0; i < size; i++)
	{
		char tmp = *((char*)p1 + i);
		*((char*)p1 + i) = *((char*)p2 + i);
		*((char*)p2 + i) = tmp;
	}
}
void my_qsort(void* base, size_t num, size_t size, int (*cmp)(const void*, const void*))
{
	size_t i = 0;
	size_t j = 0;
	for (i = 0; i < num - 1; i++)
	{
		for (j = 0; j < num - i - 1; j++)
		{
			if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0)
			{
				my_swap((char*)base + j * size, (char*)base + (j + 1) * size, size);
			}
		}
	}
}
int main()
{
	int arr[10] = { 7,6,1,2,8,9,3,5,0,4 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	my_qsort(arr, sz, sizeof(int), cmp_int);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

模拟实现qsort函数(采用冒泡排序的方式)


示例二:(排序字符数据)

#include <stdio.h>
#include <string.h>
int cmp_char(const char* p1, const char* p2)
{
	return strcmp(p1, p2);
}
void my_swap(void* p1, void* p2, size_t size)
{
	size_t i = 0;
	for (i = 0; i < size; i++)
	{
		char tmp = *((char*)p1 + i);
		*((char*)p1 + i) = *((char*)p2 + i);
		*((char*)p2 + i) = tmp;
	}
}
void my_qsort(void* base, size_t num, size_t size, int (*cmp)(const void*, const void*))
{
	size_t i = 0;
	size_t j = 0;
	for (i = 0; i < num - 1; i++)
	{
		for (j = 0; j < num - i - 1; j++)
		{
			if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0)
			{
				my_swap((char*)base + j * size, (char*)base + (j + 1) * size, size);
			}
		}
	}
}
int main()
{
	char arr[10] = {'c', 'f', 'w', 'a', 'd', 'k', 'o', 'z', 'e', 'n'};
	int sz = sizeof(arr) / sizeof(arr[0]);
	my_qsort(arr, sz, sizeof(char), cmp_char);
	for (int i = 0; i < sz; i++)
	{
		printf("%c ", arr[i]);
	}
	return 0;
}

模拟实现qsort函数(采用冒泡排序的方式)


写到这里本篇关于 qsort函数的模拟实现(冒泡排序) 的文章就到此结束了,对于这个函数的模拟实现,下来还是要多加练习才能更好的掌握。
下一篇我就正式进入对字符串的研究进行深入了解,并讲解一系列关键的字符串函数和内存函数,和它们的模拟实现。


感兴趣的的小伙伴点点赞,点点关注,谢谢大家的阅读哦!!!
精彩不容错过,点点关注,后期不错过哦!😘
你们的鼓励就是我的动力,欢迎下次继续阅读!!!😘😘😘文章来源地址https://www.toymoban.com/news/detail-447720.html

到了这里,关于模拟实现qsort函数(采用冒泡排序的方式)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

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

    作者主页: paper jie的博客_CSDN博客-C语言,算法详解领域博主 本文作者: 大家好,我是paper jie,感谢你阅读本文,欢迎一建三连哦。 本文录入于 《C语言》专栏,本专栏是针对于大学生,编程小白精心打造的。笔者用重金(时间和精力)打造,将C语言基础知识一网打尽,希望可

    2024年02月09日
    浏览(44)
  • 【C语言】——指针六:冒泡排序与qsort函数的实现

    1.1、冒泡排序的原理      在实践过程中,我们难免会碰到要给一组数据排序的情况。如果我们掌握一些排序的算法,效率就会高很多。排序的方法有方法有很多,如:希尔排序,快速排序,堆排序……,今天,我们讲的排序方法就是—— 冒泡排序 !      冒泡排序

    2024年04月16日
    浏览(49)
  • c---冒泡排序模拟qsort

    冒泡排序 冒泡排序原理:两两相邻元素进行比较 初级版 这是冒泡排序初级版,不管其原内容是否有序都会进行比较,如果原内容原本就是有序的,再每个都进行比较效率就会低下,那么这时候可以改进一下,想一个标记变量来记录是否有序,如int falg = 0; 如果无序的情况下

    2024年01月18日
    浏览(42)
  • 还在使用冒泡排序遍历数组?No No No 库函数qsort帮你搞定所有排序还不快学起来!

    🎬 鸽芷咕 :个人主页  🔥 个人专栏 :《C语言初阶篇》 《C语言进阶篇》 ⛺️生活的理想,就是为了理想的生活!    🌈 hello! 各位宝子们大家好啊,刚开始学编程的时候我们都是用冒泡来进行排序的,今天给大家介绍一下新的排序方法库函数qsort!    ⛳️ sor英文原意是

    2024年02月14日
    浏览(41)
  • 【C语言】用冒泡排序实现my_qsort

    大家好,我是苏貝,本篇博客带大家了解如何用冒泡排序实现my_qsort,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️ 用冒泡排序实现my_qsort?你或许觉得没有必要这样做,有现成的qsort函数,为什么还要自己写一个呢?于我而言,它可以让我对冒泡排序和q

    2024年02月07日
    浏览(35)
  • 实验课题——最全手机通信录实现版本(【含注释】848行代码)!!!(包括模糊查询、分类查找、模拟拨号、qsort函数实现排序、文件存储、防误触等功能)

    目录 简介: 基本要求: 代码的实现: 1、Contact.h 2、test.c 3、Cantact.c 运行效果图: 部分复杂函数流程图 前两周是本人的实验周,抽到的课题是 “手机通信录的实现” ,课题大致如下: (1)用C/C++设计出模拟手机通信录系统,实现对手机中的通信录进行管理。 (2)将通讯录用

    2024年02月07日
    浏览(46)
  • qsort函数的应用以及模拟实现

    🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨ 🐻推荐专栏: 🍔🍟🌯 c语言进阶 🔑个人信条: 🌵知行合一 🍉本篇简介::介绍库函数qsort函数的模拟实现和应用 金句分享: ✨追光的人,终会光芒万丈.✨ 库函数查询网站(建议使用 旧版本 查询) 头文件: stdlib.h 功能介绍: 使用函数 确定顺

    2024年02月02日
    浏览(35)
  • 【C语言】轻松模拟实现qsort函数

    君兮_的个人主页 勤时当勉励 岁月不待人 C/C++ 游戏开发 Hello,米娜桑们,这里是君兮_,我们今天接着上回更新的内容,讲讲我们如何模拟实现自己的qsort函数, 废话不多说,我们开始今天的内容。 关于这方面的内容已经在上篇博客中具体介绍了,这里不再缀叙,感兴趣的话可

    2024年02月16日
    浏览(32)
  • 『C语言进阶』qsort函数及模拟实现

    🔥 博客主页 : 小羊失眠啦 🔖 系列专栏 : C语言 🌥️ 每日语录 : 没有退路,只能让自己变得强大 ❤️ 感谢大家点赞👍收藏⭐评论✍️ 在上篇指针进阶中,我们对函数指针、函数指针数组、函数指针数组指针以及回调函数有了一定的了解,文章末尾简单的对qsort函数进

    2024年02月07日
    浏览(41)
  • 【C语言】回调函数(qsort)与模拟实现

    何思何虑,居心当如止水;勿取勿忘,为学当如流水。— 出自《格言联璧·学问类》 解释:无思无虑,心境应当平静如水;不求冒进也不忘记,学业当如流水一般永无止境。 这篇博客我们将会理解回调函数这个概念,以及借用qsort帮助理解,并且最终用qsort的思路来实现冒泡

    2024年02月16日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包