2021-09-15

qsort:“快排”的模拟实现



```c

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
#pragma warning(disable:4996)
typedef struct Student//定义结构体
{
	int id;
	char name[10];
	int age;
	char sex[3];
}Student;
int my_intcompare(const void *s1, const void *s2)//整形比较大小
{
	return *(int*)s1 - *(int*)s2;
}
int my_charcompare(const void *s1, const void *s2)//字符比较大小
{
	return *((char*)s1) - *((char*)s2);
}
int my_strcompare(const void *elem1, const void *elem2)//字符串比较大小
{
	return strcmp(*((char**)elem1), *((char**)elem2));
}

int my_structcompare(const void *elem1, const void *elem2)//结构体根据年龄比较大小
{
	Student *s1 = (Student*)elem1;
	Student *s2 = (Student*)elem2;
	return s1->age - s2->age;
}
int my_floatcompare(const void *elem1, const void *elem2)//单精度类型数据比较大小
{
	const float* s1 = elem1;
	const float* s2 = elem2;
	if (*s1 > *s2)
		return 1;
	else if (*s1 == *s2)
		return 0;
	return -1;
}
int my_doublecompare(const void *elem1, const void *elem2)//双精度类型数据比较大小
{
	const double* s1 = elem1;
	const double* s2 = elem2;
	if (*s1 > *s2)
		return 1;
	else if (*s1 == *s2)
		return 0;
	return -1;
}
void my_qsort(void *base, size_t n, size_t width, int(*compare)(s1,s2))
{
	assert(base!=NULL);
	void *tmp = malloc(width);//为了提高效率,尽量减少空间的多次重复申请和被重复释放,所以将定义tmp的工作放到了for循环的外边
	for (int i = 0; i < n - 1; i++)//冒泡排序
	{
		for (int j = 0; j < n - 1 - i;j++)
		{
			if (compare(((char*)base + j*width), ((char*)base + (j + 1)*width))>0)//此处的compare实际为:int (*compare)(const void*,const void*),通过函数指针来调用相应的函数
			{//这里通过使用memcpy来实现数据的交换
				memcpy(tmp, ((char*)base + j*width), width);
				memcpy(((char*)base + j*width), ((char*)base + (j + 1)*width),width);
				memcpy(((char*)base + (j + 1)*width),tmp, width);
			}
		}
	}
	free(tmp);
}
void Print_Array(int *s, int left, int right)//打印整型数组
{
	assert(s != NULL);
	while (left < right)
	{
		printf("%d ", s[left]);
		left++;
	}
	printf("\n");
}
void Print_Array1(char *s, int left, int right)//打印字符数组
{
	assert(s != NULL);
	for (int i = left; i < right; i++)
	{
		printf("%c ", s[i]);
	}
	printf("\n");
}
void Print_Array2(char *s[], int left, int right)//打印字符串
{
	assert(s != NULL);
	for (int i = left; i < right; i++)
	{
		printf("%s ", s[i]);
	}
	printf("\n");
}
void Print_Array3(Student stu[], int left, int right)//打印结构体数组
{
	assert(stu != NULL);
	for (int i = left; i < right;i++)
	{
		printf("%d  %s  %d  %s\n", stu[i].id,stu[i].name,stu[i].age,stu[i].sex);
	}
	printf("\n");
}
void Print_Array4(float* s, int left, int right)//打印单精度数组
{
	assert(s != NULL);
	for (int i = left; i < right; i++)
	{
		printf("%f ", s[i]);
	}
	printf("\n");
}
void Print_Array5(double* s, int left, int right)//打印双精度数组
{
	assert(s != NULL);
	for (int i = left; i < right; i++)
	{
		printf("%f ", s[i]);
	}
	printf("\n");
}
int main()
{
	int ar[] = {32, 95, 55, 52 };
	char br[] = { 'a', 'g', 'h', 'y', 'm' };
	char* cr[] = { { "likethis" }, {"missyou"},{ "thedown" }};
	Student stu[] = { { 555, "张三", 21, "男" }, { 666, "李四", 19, "男" }, {777,"二狗",20,"男"} };
	float dr[] = { 0.5f, 0.4f, 0.8f, 0.2f };
	double er[] = { 7.8, 12, 6.3, 5.2 };
	int n = sizeof(ar) / sizeof(ar[0]);
	int n1 = sizeof(br) / sizeof(br[0]);
	int n2 = sizeof(cr) / sizeof(cr[0]);
	int n3 = sizeof(stu) / sizeof(stu[0]);
	int n4 = sizeof(dr) / sizeof(dr[0]);
	int n5 = sizeof(er) / sizeof(er[0]);
	Print_Array(ar, 0, n);
	my_qsort(ar, n, sizeof(int), my_intcompare);
	Print_Array(ar, 0, n);

	Print_Array1(br, 0, n1);
	my_qsort(br, n1, sizeof(char), my_charcompare);
	Print_Array1(br, 0, n1);

	Print_Array2(cr, 0, n2);
	my_qsort(cr, n2, sizeof(char*), my_strcompare);
	Print_Array2(cr, 0, n2);

	Print_Array3(stu, 0, n3);
	my_qsort(stu, n3, sizeof(Student), my_structcompare);
	Print_Array3(stu, 0, n3);

	Print_Array4(dr, 0, n4);
	my_qsort(dr, n4, sizeof(float), my_floatcompare);
	Print_Array4(dr, 0, n4);


	Print_Array5(er, 0, n5);
	my_qsort(er, n4, sizeof(double), my_doublecompare);
	Print_Array5(er, 0, n5);
	system("pause");
	return 0;
}

模拟qsort的实现要求:1.对冒泡排序的掌握。2. 要能理解void* 空类型指针的含义和他的灵活用法3. 对函数指针的彻底了解能够使函数指针来灵活的使代码的冗余性降低很多,同时也会提高代码的执行效率。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

倚心

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

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

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

打赏作者

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

抵扣说明:

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

余额充值