文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

C语言qsort函数用冒泡排序实现过程详解

2023-02-14 18:00

关注

前言

这篇文章就是指针进阶的收尾环节了,相信看过C语言进阶——指针(下)的小伙伴一定还记着文章末尾的回调函数吧。这篇文章就是借qsort函数的模拟实现来给小伙伴们展示一下回调函数的运用。

1.冒泡排序的实现

在实现qsort函数,相信有的小伙伴对冒泡排序还存有疑惑,甚至是第一次接触这个名词,那么我们就先来讲讲冒泡排序。

1.1冒泡排序的概念

“冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行,直到没有相邻元素需要交换,也就是说该元素列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。

相信聪明的你已经知道了冒泡排序是一种依次比较相邻元素并按照相应规则进行排序的排序方法。

在这种排序过程中,重要的元素共有两个,分别是冒泡排序的趟数以及比较的次数。一般而言,趟数是元素的个数减一得到,为什么不等于元素的个数呢?因为每进行一趟冒泡排序,就会有一个元素来到它正确的位置,所以当除了最后一个元素以外的其他元素都来到了正确位置的时候,那么最后一个元素也一定处于正确位置。

说完趟数,再来聊聊比较次数。有亲自实践的小伙伴们一定发现了在进行第一趟冒泡排序的时候,比较的次数是最多的,是除了第一个元素以外的所有元素都要与之比较,也就是元素的个数减一,但是随着趟数的增加,比较的次数也会随之减少,究其原因,是因为每经过一次冒泡排序,就会有一个元素来到正确的位置,那么这个正确的元素也就无需参加后续的比较了。

那么具体的代码实现究竟是怎么样呢?接下来就让我们一起揭开它神秘的面纱,一探究竟!

1.2具体代码的实现

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 tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
            }
		}
	}
}

2.qsort函数

在了解完冒泡排序之后,有的小伙伴还是第一次见到qsort函数,那么下面我们就来简单介绍一下qsort函数。

首先我们要清楚的是qsort函数是库里面的函数,所以我们在使用的时候要引用头文件<stdlib.h>。

然后我们再来了解一下这个函数的各个部分。第一个是返回类型,从上图中我们可以看到返回类型是void,也就是说当我们在引用这个函数的时候,它并不会返回任何参数。第二个是参数部分,第一个参数是一个指针变量,第二、三个参数是无符号的整型变量,第四个就是我们之前讲解过的函数指针变量。在第四个参数部分也就体现了回调函数这一功能。

最后我们来讲讲这个函数该怎么使用。在引用完头文件后,我们下一步就是要对这个函数进行传参,在意义上分别是要排序的对象,元素个数,元素大小(以字节为单位),判断是否交换的函数(根据需求自写)。

说到第四个参数所指向的函数需要根据需求自己来写,可能有小伙伴就疑惑了,到底要怎么写呢。别怕,上面这幅图片可以说是为我们函数的书写提供了方向。首先你要确保你书写的函数的返回类型为int,并且依据交换的原则来进行返回值的代码书写。拿整型数组排序为例,如果你想要最终数组的整形呈现升序排序,那么如果两个数是降序排序就应该返回小于0的整型。具体代码的实现如下,以整形数组和结构体为例。

//用qsort函数实现各种类型的排序
//整形数组的排序
int cmp_int(void const* e1, void const* e2)
{
	return *(int*)e1 - *(int*)e2;
}
int main()
{
	int i = 0;
	int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, 4, cmp_int);
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}
//结构体的排序
struct stu
{
	char name[20];
	int  age;
};
int cmp_age(void const*e1, void const*e2)
{
	return (((struct stu*)e1)->age - ((struct stu*)e2)->age);
}
int cmp_name(void const* e1, void const* e2)
{
	return strcmp(((struct stu*)e1)->name ,((struct stu*)e2)->name);
}
int main()
{
	struct stu Stu[3] = { {"zhangsan", 20},{"wangwu", 42},{"lisi",29}};
	int sz = sizeof(Stu) / sizeof(Stu[0]);
	//qsort(Stu, sz, sizeof(Stu[0]), cmp_age);
	qsort(Stu, sz, sizeof(Stu[0]), cmp_name);
	return 0;
}

3.qsort函数的实现

随着我们学习的不断深入,类型的不断丰富,我们会发现上面的冒泡排序已然满足不了我们的需求,诸如结构体的排序,这种代码已经是无能为力了。那么接下来我们就自己来利用冒泡排序的原理来书写qsort函数。

//实现元素的交换
void swap(char* e1, char* e2, size_t sz)
{
	size_t i = 0;
	for (i = 0; i < sz; i++)
	{
		char tmp = 0;
		tmp = *e1;
		*e1 = *e2;
		*e2 = tmp;
		e1++;
		e2++;
	}
}
//qsort函数的自定义
void bubble_sort(void* base, size_t num, size_t size, int (*compar)(const void*e1, const void*e2))
{
	size_t i = 0;
	size_t j = 0;
	//冒泡排序的趟数
	for (i = 0; i < num-1; i++)
		{
			//比较的次数
			for (j = 0; j < num - i - 1; j++)
			{
				if (compar((char *)base+j*size,(char*)base+(j+1)*size)>0)
				{
					//交换
					swap((char*)base + j*size, (char*)base + (j + 1)*size, size);
				}
			}
		}
}

到此这篇关于C语言qsort函数用冒泡排序实现过程详解的文章就介绍到这了,更多相关C语言qsort函数内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯