排序函数-----Qsort函数

qsort函数:可以实现不同类型数据的排序:

函数使用:

整形数组排序:

输入数组:a[6]={ 3,5,96,8,99,2 };

排序后的数组:a[6]={ 2,3,5,8,96,98 };

结构体数组

数组结构体数组:struct human s[3] = { {"zbc",20},{"pcd",30},{"ade",50} };

排序后的数组结构体数组:struct human s[3] = { {"ade",50},{"pcd",30},{"abc",20} };

函数实现:

current_bubble_sort()函数------基于冒泡排序的思想设计实现库函数qsort的相关功能

1.因为预先不知道要排序的数据类型,所以用四个参数来确定相关信息:

1.1待排序数组的首地址 base,因为不知道数组元素的类型,所以定义为void* base;

1.2数组元素个数 num,定义为int num;

1.3数组元素长度 width,定义为 int width;

1.4判断函数function函数,定义为 int (*function) (const void* e1,const void* e2);

2.搭建冒泡函数框架:

2.1对于num个元素,需要排序num-1个数据,所以外层确定循环次数时

2.2每一次排序时,要操作的数据个数也是不同的,为num-1-i

void current_bubble_sort(void* base, int num, int width, int (*function)(const  void* e1, const  void* e2))
{
	for (int i = 0; i < num - 1; i++)
	{
		for (int j = 0; j < num - 1 - i; j++)
		{		
            ?
		}
	}
}

3.判断是否需要交换元素的顺序:

3.1使用function函数比较两个数的大小,function函数返回值是1,说明第一个元素大于第二个元素,返回值是0时,说明两个元素相等,返回值是-1,说明第一个元素小于第二个元素。

3.2如果默认是升序排序,那么返回值是1时,进行排序。

3.3function函数的参数分别是两个待比较元素的地址,因为只涉及到函数的比较,不涉及函数数据的改变,为了安全起见,用const函数修饰地址。

3.4function的函数参数是要比较两个数组元素,用base(数组首元素地址)+步长*j。

3.5将function函数的地址指针强制转化为char* 类型,步长为1。

3.6实现结果: if (function((char*)base+j*width, (char*)base+(j+1)*width) > 0)

4.交换函数swap函数

4.1核心就是交换两个待交换数据的单个字节。

4.2参数是要交换元素的地址和元素类型的宽度

4.3最终代码为:void swap(char* swap1, char* swap2, int swapwidth)

5.打印函数

5.1整型数组打印没什么好说的

5.2结构体数组打印内容时,注意正确的打印格式,指针->结构体变量名;

最终代码:

#include <stdio.h>
#include <string.h>
//用冒泡排序的思想模仿qsort函数实现一个通用的排序算法
struct human
{
	char name[20];
	int age;
};
void swap(char* swap1, char* swap2, int swapwidth)  // 单个字节传输
{
	for (int i = 0; i < swapwidth; i++)
	{
		char temp = *swap1;
		*swap1 = *swap2;
		*swap2 = temp;
		swap1++;
		swap2++;
	}
}
int function_int(const  void* e1, const  void* e2)
{
	return (*(int*)e1) - (*(int*)e2);
}
int function_struct(const  void* e1, const  void* e2)
{
	return strcmp(((struct human*)e1)->name, ((struct human*)e2)->name);
}
void current_bubble_sort(void* base, int num, int width, int (*function)(const  void* e1, const  void* e2))
{
	for (int i = 0; i < num - 1; i++)
	{
		for (int j = 0; j < num - 1 - i; j++)
		{
			if (function((char*)base+j*width, (char*)base+(j+1)*width) > 0)
			{
				//大于零、升序交换
				//实现方法不知道,需要函数使用者编写
				swap((char*)base + j * width, (char*)base + (j + 1) * width, width);//直接交换字节
			}

		}
	}
}
void print1(int a[], int sz)
{
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", a[i]);
	}
}
void print2(struct human s[], int sz)
{
	for (int i = 0; i < sz; i++)
	{
		printf("%s %d\n", (*(s + i)).name, (s + i)->age);
	}
}

int main()
{
	int a[6] = { 3,5,96,8,99,2 };
	int sz1 = sizeof(a) / sizeof(a[0]);

	struct human s[3] = { {"zbc",20},{"pcd",30},{"ade",50} };
	int sz2 = sizeof(s) / sizeof(s[0]);

	current_bubble_sort(a, sz1, sizeof(a[0]), function_int);
	current_bubble_sort(s, sz2, sizeof(s[0]), function_struct);

	printf("数组排序后的结果:->\n");
	print1(a, sz1);
	printf("\n");
	printf("结构体按照首元素字符排序后的结果:->\n");
	print2(s, sz2);
	return 0;
}

特别鸣谢:哔哩哔哩比特鹏哥的视频教学课。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hskwcy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值