C语言标准库函数qsort( )——数据排序

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

  c语言排序库函数,排序算法,C语言,c语言,排序算法

大家好!我是保护小周ღ,本期为大家带来的是深度解剖C语言标准库函数 qsort(),qsort()函数他可以对任意类型的数据排序,博主会详细解释函数使用方法,以及使用快速排序的左右指针法模拟实现函数功能这样的排序确定不来学习一下吗???

 c语言排序库函数,排序算法,C语言,c语言,排序算法

c语言排序库函数,排序算法,C语言,c语言,排序算法

目录

一、qsort()函数简介

二、qsort() 函数的参数

三、qsort() 函数的使用

3.1 对整型数据排序 

3.2 对结构体类型数据排序

 四、快速排模拟实现qsort()函数


一、qsort()函数简介

qsort() 函数是C语言标准库提供的排序函数,q==Quick,函数内部是以快速排序的思想实现的,那qsort() 函数的意义是什么呢?内部居然还使用别的排序的思想。因为常规排序是写死的,假如原先是对整型数据的排序,现在要对结构体类型的数据排序,则需要修改函数参数,函数内部数据也要相应的修改。而qsort()函数他可以对任意类型的数据排序,比如说,可以直接排整型数据,也可以排结构体类型的数据,甚至是字符串数据,通用性极强。这样的排序确定不来学习一下吗???


二、qsort() 函数的参数

c语言排序库函数,排序算法,C语言,c语言,排序算法

很明显 qsort()函数具有4个参数,接下来博主来解剖一下这些参数代表着什么意思。

1.   void * base : 首先来了解一下什么是 void* ,这个是无具体类型的指针,void * 的指针是非常宽容的,可以接收任意类型的数据。常常用来临时存放数据,等到需要使用数据时,我们必须要强制类型转换成某一具体类型的数据,才能对数据进行操作。

c语言排序库函数,排序算法,C语言,c语言,排序算法

对void *pa,接收了一个整型 a 的地址,我们对指针pa 进行强制类型转换(int*),再解引用 pa即可对变量a 进行操作。

 void *base 存的就是待排序数据的起始地址(不能直接访问)。

 这个参数是 qsort() 函数能够对任意数据排序的基础。 

2. size_t  num : 记录待排序数据元素个数。

3. size_t  size  : 记录待排序数据任意一个元素的所占的字节数(元素的大小)。

4. int  (*compar) (const  void*  , const  void* ) : 

这其实是一个函数类型的指针,可以用来存储函数的地址,然后也提前声明了函数的参数,返回值

返回值是 int 类型,参数部分是两个 void * 类型的接收。这个函数的作用是来比较两个参数的大小,然后返回比较果结,怎么比呢? 如果是整型数据使两个参数相减,返回结果。如果是字符串,我们可以使用   strcmp(“字符串”,“字符串”);strcmp 函数的返回值也是整型数据(这个是根据对应的场景,选择比较方式),即可得到相应的结果。

这第四个参数需要我们自己设计实现,函数的作用就是比较任意两个参数,返回一个整型数据,就可以利用这个数据来判断两个元素大小,所以这是个比较排序。

c语言排序库函数,排序算法,C语言,c语言,排序算法


三、qsort() 函数的使用

qsort()函数包含在 stdlib.h库里,所以我在使用前需要申明一下。

3.1 对整型数据排序 

#include<stdio.h>
#include<stdlib.h>//头文件声明

//判断两个元素的大小
int Compar(void const *p1,void const *p2)//无具体类型的指针接收数据,使用时强制类型转换。
{
    //两个整型数据相减,即可即可得到三种信息>,<,=
    return (*(int*)p1 - *(int*)p2) *(-1); //利用乘-1改变符号控制升序还是降序
}

//打印
void Print(int *arr,int n)
{
    for (int i=0;i<n;++i)
    {
        printf("%d ",arr[i]);
    }
}

int main()
{
    int arr[] = { 8,6,4,2,3,7,1,2,3,10,9 };
    int len = sizeof(arr) / sizeof(arr[0]);//记录数组元素个数
    int size = sizeof(arr[0]);//记录某一个元素的大小所占的字节数

    //库函数
    qsort(arr, len, size, Compar);
    //第四个参数,直接传函数的地址,函数名代表函数的地址,由函数指针接收。

    //打印
    Print(arr, len);
    return 0;
}

c语言排序库函数,排序算法,C语言,c语言,排序算法


3.2 对结构体类型数据排序

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct Student//定义一个Student类型的结构体
{
	char name[12]; //姓名
	int age;       //年龄
	char StuID[8]; //学号
}Student;//typedef,重命名一下,简化。

//比较任意两个元素的大小。
int CmpSort(const void* p1, const void * p2)
{
	//return ( ((Student*)p1)->age - ((Student*)p2)->age );//根据年龄来比

	return (strcmp(((Student*)p1)->name,((Student*)p2)->name));//按照姓名的首字母来比较
}

//打印
void Print(Student* ps,int n)
{
	for (int i=0;i<n;++i)
	{
		printf("%s %d %d\n",ps[i].name,ps[i].age,ps[i].StuID);
	}
}

int main()
{
	Student student[3] = { {"张三",18,"21933321"},{"李四",20,"21933323"},{"王老五",19,"21933322"}};

	int len = sizeof(student) / sizeof(student[0]);//统计Student 类型,student数组的元素的个数
	int size = sizeof(student[0]);//统计某一个Student 元素所占的字节数。
	//库函数
	qsort(student,len,size,CmpSort);

	Print(student,len);//打印
	
	return 0;
}

c语言排序库函数,排序算法,C语言,c语言,排序算法


 四、快速排模拟实现qsort()函数

好了经过以上三节内容的铺垫,相信大家应该对 qsort() 函数的用法,功能明白了,接下来我们就要来模拟实现函数内部。上文说到排序思想是用快速排序的思想。那博主今天就用快速排序——左右指针法来模拟实现挖坑法有一点复杂(下文解释)。

老铁如果对快速排序的几种排序思想还有什么不明白的可以学习博主的专栏。文章最后会贴。

什么是左右指针法?一张图带你搞定:

c语言排序库函数,排序算法,C语言,c语言,排序算法

利用递归来继续分割区间,分割后继续单趟排,最后实现整体排序,排序结束。

算法逻辑弄明白了,现在还有一个问题,那就是函数内部,不知道我们要对什么类型的数据进行排序,我们虽然使用 void * 无指定类型的指针来接收数据,内部怎么根据数据的类型来进行强制类型转换呢?不转换无法处理数据。

大家回忆一下,我们qsort()函数是不是有四个参数,其中有一个参数就是 某一个元素所占的字节大小。size。

我们是不是可以将 void * 转换成 char * ,char* 的指针每一次只能访问一个字节的内容。

举个例子:

c语言排序库函数,排序算法,C语言,c语言,排序算法c语言排序库函数,排序算法,C语言,c语言,排序算法

现在访问数据元素的问题解决了,那怎么交换数据元素的位置呢?

还是建立在访问元素的基础上,先找到需要交换的元素的位置,再根据 size 的大小一个字节一个字节的交换数据。

//交换数据
void Swap(char* base1, char* base2, int size)
{
	for (int i = 0; i < size; ++i)//按字节转换
	{
		char tmp = *base1;
		*base1 = *base2;
		*base2 = tmp;
		++base1;
		++base2;	
	}
}

这一趟下来,两个元素的就实现了交换。

完整版代码:

#include <stdio.h>
#include <stdlib.h>

int Cmp_qsort(void const* p1, void const* p2)//用户输入,
{
	int size1 = (*(int*)p1 - *(int*)p2);
	return size1;
}

//交换数据
void Swap(char* base1, char* base2, int size)
{
	for (int i = 0; i < size; ++i)//按字节转换
	{
		char tmp = *base1;
		*base1 = *base2;
		*base2 = tmp;
		++base1;
		++base2;	
	}
}

//模拟实现
void _Quick_qsort(void const* base, int left, int right, int size, int(*Cmp_qsort)(void const* p1, void const* p2))
{
	if (left >= right)
	{
		return;
	}

	int begin = left;
	int end = right;
	int key = begin;//记录坑位的下标、

	while (begin < end)
	{

		while (begin < end && (Cmp_qsort((char*)base+ key*size, (char*)base + end * size) <= 0))
			--end;

		while (begin < end && (Cmp_qsort((char*)base+ key*size, (char*)base + begin * size) >= 0))
			++begin;
		Swap((char*)base +begin * size, (char*)base+end*size, size);

	}
	Swap((char*)base + begin * size, (char*)base + key * size, size);

	_Quick_qsort(base, left, begin - 1, size, Cmp_qsort);
	_Quick_qsort(base, begin + 1, right, size, Cmp_qsort);

}


//过渡一下
void Quick_qsort(void const* base, int len, int size,int(*Cmp_qsort)(void const *p1,void const *p2))
{
	_Quick_qsort(base, 0, len - 1, size, Cmp_qsort);//左右区间写入参数,
}

//打印
void Print(int* a, int n)
{
	for (int i = 0; i < n; ++i)
	{
		printf("%d ", a[i]);
	}
}

//快排左右指针法
int main()
{
	int a[] = {6,1,2,10,7,9,9,3,4,5,10,8};
	int len = sizeof(a) / sizeof(a[0]);
	int size = sizeof(a[0]);

	Quick_qsort(a, len, size,Cmp_qsort);//快速排序模拟实现

	Print(a, len);//打印
	return 0;

}

c语言排序库函数,排序算法,C语言,c语言,排序算法

这个模拟是争对于顺序结构的数据,而链式结构要采用不同的办法。

不采用快排的挖坑发的原因是:我们需要一个类型大小的空间存坑值,这个时候我们只能根据size(一个元素所占的字节数)动态开辟一个char *的数组,一个字节一个字节的存储。如果光定义指针指向,那坑值指针,会随着指向地址的元素的变化而变化。 


至此,C语言的深度解剖 qsort() 函数,博主已经分享完了,希望对大家有所帮助,如有不妥之处欢迎批评指正。

 c语言排序库函数,排序算法,C语言,c语言,排序算法

本期收录于博主的专栏——数据排序,适用于编程初学者,感兴趣的朋友们可以订阅,查看其它“经典数据排序”。排序算法_保护小周ღ的博客

感谢每一个观看本篇文章的朋友,更多精彩敬请期待:保护小周ღ  *★,°*:.☆( ̄▽ ̄)/$:*.°★* 

文章存在借鉴,如有侵权请联系修改删除! c语言排序库函数,排序算法,C语言,c语言,排序算法​​文章来源地址https://www.toymoban.com/news/detail-779959.html

到了这里,关于C语言标准库函数qsort( )——数据排序的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【C语言】qsort()函数详解:能给万物排序的神奇函数

    🦄 个人主页 :修修修也 🎏 所属专栏 :C语言 ⚙️ 操作环境 : Visual Studio 2022   目录 一.qsort()函数的基本信息及功能 二.常见的排序算法及冒泡排序 三.逐一解读qsort()函数的参数及其原理 1.void* base 2.size_t num 3.size_t size 4.int (*compar)(const void*,const void*) 四.使用qsort()函数完成整形,

    2024年02月06日
    浏览(48)
  • C语言题目 - 调用qsort函数对数组进行排序

    如题 其实没什么难的,只要严格按照 qsort 函数的参数来填充即可,这里要用到 函数指针 。 qsort 函数的原型如下: void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void *)); 参数说明: base :指向需要排序的数组的指针,数组中每个元素的大小应为 size 字节。

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

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

    2024年04月16日
    浏览(50)
  • 【C语言】回调函数,qsort排序函数的使用和自己实现,超详解

    先记录一下访问量突破2000啦,谢谢大家支持!!! 这里是上期指针进阶链接,方便大家查看:添加链接描述 大家好呀,今天分享一下上期指针进阶中剩余的内容——回调函数,这个很重要滴,让我们一起来学会学懂他吧!!! 标准概念: 回调函数就是一个通过函数指针调

    2024年02月12日
    浏览(53)
  • 冒泡排序模拟实现qsort()函数

    要模拟qsort()函数,我们首先要知道qsort()函数的特点: 使用快速排序的方法。 适用于任何数据类型的排序。 但由于部分学者还没有学习快速排序算法,所以本篇博客采用冒泡排序来模拟功能类似于qsort()的函数bubble_sort。 C库对qsort()函数解释: 我们得到的关于qsort()函数参

    2024年02月16日
    浏览(56)
  • 用冒泡排序实现快速排序(qsort函数),指针进阶实例

    目录   1、qsort函数是什么 2、冒泡排序实现指针进阶 2.1 主函数 2.2 功能函数声明​编辑 2.3 my_qsort函数介绍 2.4 Swap函数 总结           qsort函数是c语言自带的函数,其功能是实现快速排序。我们来看一下他的参数和返回值:         以上就是qsort的参数和返回值,可以看到,

    2024年02月21日
    浏览(44)
  • 对任意类型数都可以排序的函数:qsort函数

    之前我们学习过冒泡排序: 可以看出这样的排序方法只适用于整形类型的数 那么是否有一种排序可以满足所有类型都适用的排序呢? qsort函数排序 应用: 在这里需要补充一下void* 类型的指针 当然qsort函数排序既然可以实现任意类型,那么我们换几个类型试一下; 结构体类

    2024年02月14日
    浏览(42)
  • 模拟实现qsort函数(采用冒泡排序的方式)

    前言: 之前我在C语言:指针详解【进阶】后篇中提到了 qsort函数 , qsort函数 作为一个库函数,在我们日常的代码编写中可能会用到,在上面提到的文章中我们也进行使用了这个函数,大家也了解了一些这个函数的使用方法,但我们作为学习者,我们不仅要会用,还要知道这

    2024年02月05日
    浏览(44)
  • c语言用冒泡排序模拟实现qsort排序

    1、简单介绍冒泡排序 冒泡排序就是两两相邻元素进行比较,如果不满足顺序就进行交换。现有一组整数,将其用冒泡排序实现排序为升序。 假设有这样一组整数:9 8 7 6 5    由此可知,如果一个整型数组有num个元素,则需走num-1趟,若走在第i趟,则在第i趟内需要比较num-1

    2024年02月15日
    浏览(46)
  • C/C++qsort函数的实现(冒泡排序)

     个人主页: 仍有未知等待探索_数据结构,小项目,C语言疑难-CSDN博客 专题分栏: C语言疑难_仍有未知等待探索的博客-CSDN博客 目录 一、引言 二、讲解实现 1、给整型数组排序   排序实现 总代码  2、qsort中参数cmp函数怎么实现 1.浮点型 2.结构体类型  1、第一个参数是void*b

    2024年02月07日
    浏览(39)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包