冒泡排序模拟实现qsort函数

一、1.函数了解:在c语言中qsort函数是一个排序函数,它不光可以排序整数,字符,也可以根据结构体的组成成分来排序结构体,它在c语言库中是通过快速排序的方式来实现,其头文件为stdlib.h。

2.qsort函数:从上面我们知道qsort是一个排序的函数,所以并不需要返回值,qsort函数有四个参数,按顺序依次为 待排序元素的首地址(指针),排序数组元素的个数,一个元素所占的字节,函数指针。

3,qsort如何实现排序的:qsort函数的最后一个参数是一个函数指针,它所指向的函数可以比较两个数的大小,根据返回值来决定是否交换两个数,如果返回值为正数则交换。我们知道该函数可以比较各种类型的数据,所以我们需要将比较的两个数的类型以void形式传入比较函数,同时为了防止自己改变指针所指向的内容,我们给其限定const。

四、函数实现:
我们这里使用的是冒泡排序的方式实现排序,所以想要完成以下代码请先学习冒泡排序;
1、我这里先使用整形数组实现,便于理解,在文章后面会给出字符类型的实现形式:

void test()
{
	int arr[10]={3,4,5,2,1,6,7,8,9,0};//输入乱序的元素
	int sz=sizeof(arr)/sizeof(arr[0]);//求出数组元素的个数
	my_qsort(arr,sz,sizeof(arr[0]),compar);//按照传参顺序依次输入
	int *p=arr; 
	print(p,sz);
}
int main()
{
	test();
	return 0;
}

下面就是比较两元素大小的函数

int compar(const void*p1,const void*p2)
{
	return *(int*)p1-*(int*)p2;//通过返回值来判断是否交换元素
	//你要排序什么元素就将p1,p2强制转化为什么类型
	//例如return strcmp(((struct stu*)p1)->name,((struct stu*)p2)->name);
	//strcmp为字符串比较函数,其返回值也为0或1
}

当上面这个函数返回一个int的数据时我们需要根据正负来确定是否交换元素,我们知道该函数可以交换各种类型的数据,那么我们就需要字节来作为最小单位,因为我们知道int(4字节),char(1个字节),如果我们定义最小交换字节为4的话是实现不了字符类型数据的交换:

void my_qsort(void*p,size_t sz,size_t width,int (*ptr)(const void*,const void*))
{//size_t是无符号整型,因为传的参数是数组的大小,以及单个元素所占的字节,其值为整数
//最后一个函数就是传入比较函数的地址以便下面使用
	int i=0;
	for(i=0;i<sz-1;i++)
	{
		for(int j=0;j<sz-i-1;j++)
		{
			if(compar((char*)p+j*width,(char*)p+(j+1)*width)>0)
			{
				sweap((char*)p+j*width,(char*)p+(j+1)*width,width);
				//通过冒泡排序的形式来比较两个数据的大小,最后通过sweap函数来
				//交换比较的函数
			}
		}
	}
}

下面就是完成交换的函数,上面我们说过比较的数据会以字节来的形式交换:

void sweap(char*p1,char*p2,size_t width)//width为单个元素的字节
{
	for(int i=0;i<width;i++)//里面会单个单个字节来交换
	{
		char tem=*p1;
		*p1=*p2;
		*p2=tem;
		p1++;
		p2++;
	}
}

最后我们只需要定义一个打印的函数

void print(int *p,int sz)
{
	for(int i=0;i<sz;i++)
	{
		printf("%d ",p[i]);
	}
}

这就是qsort来排序整形数据的方式
下面是整个函数的代码

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

void print(int *p,int sz)
{
	for(int i=0;i<sz;i++)
	{
		printf("%d ",p[i]);
	}
}
int compar(const void*p1,const void*p2)
{
	return *(int*)p1-*(int*)p2;
}

void sweap(char*p1,char*p2,size_t width)
{
	for(int i=0;i<width;i++)
	{
		char tem=*p1;
		*p1=*p2;
		*p2=tem;
		p1++;
		p2++;
	}
}

void my_qsort(void*p,size_t sz,size_t width,int (*ptr)(const void*,const void*))
{
	int i=0;
	for(i=0;i<sz-1;i++)
	{
		for(int j=0;j<sz-i-1;j++)
		{
			if(compar((char*)p+j*width,(char*)p+(j+1)*width)>0)
			{
				sweap((char*)p+j*width,(char*)p+(j+1)*width,width);
			}
		}
	}
}
void test()
{
	int arr[10]={3,4,5,2,1,6,7,8,9,0};
	int sz=sizeof(arr)/sizeof(arr[0]);
	my_qsort(arr,sz,sizeof(arr[0]),compar);
	int *p=arr; 
	print(p,sz);
}
int main()
{
	test();
	return 0;
}

下面我会给出qsort来通过比较结构体中的char[]来排序的代码

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

struct stu
{
	char name[20];
	int age;
	int num;
};
	
int ptr(const void*p1,const void*p2)
{
	return strcmp(((struct stu*)p1)->name,((struct stu*)p2)->name);
}

void print(struct stu *p,int sz)
{
	for(int i=0;i<sz;i++)
	{
		printf("%s %d %d\n",p[i].name,p[i].age,p[i].num);
	}
}

void test()
{
	struct stu arr[3];
	printf("请输入三个人的信息:");
	int sz=sizeof(arr)/sizeof(arr[0]);
	for(int i=0;i<sz;i++)
	{
		scanf("%s %d %d",arr[i].name,&arr[i].age,&arr[i].num);
	}
	qsort(arr,sz,sizeof(arr[0]),ptr);
	struct stu *p=arr;
	print(p,sz);
}

int main()
{
	test();
	return 0;
}

其比较部分是通用的,大家可以试着自己改写

  • 13
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值