C语言--回调函数实列 模拟qsort函数

Posted 4nc414g0n

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言--回调函数实列 模拟qsort函数相关的知识,希望对你有一定的参考价值。

qsort函数简介

  • qsort,quick_sort快速排序
  • qsort函数包含在C 标准库 - <stdlib.h>中

qsort 的函数原型是:
void qsort(voidbase,size_t num,size_t width,int(__cdeclcompare)(const void*,const void*))

  • void*base为要排序的数组名(地址)
  • size_t num为元素个数
  • size_t width为每个元素所占空间大小,字节数
  • int(__cdecl*compare)(const void*,const void*)为库函数作者提供给使用者自己编写的一个比较函数返回值为int
    如果compar返回值小于0(< 0),那么p1所指向元素会被排在p2所指向元素的左面;
    如果compar返回值等于0(= 0),那么p1所指向元素与p2所指向元素的顺序不确定;
    如果compar返回值大于0(> 0),那么p1所指向元素会被排在p2所指向元素的右面。

__cdecl 是C Declaration的缩写(declaration,声明),表示C语言默认的函数调用方法:所有参数从右到左依次入栈,这些参数由调用者清除,称为手动清栈。被调用函数不会要求调用者传递多少参数,调用者传递过多或者过少的参数,甚至完全不同的参数都不会产生编译阶段的错误。

例主函数代码

struct Stu
{
	char name[20];
	int age;
};
int main()
{
	int arr[10]={1,4,2,5,3,6,9,7,8,10};
	char arr1[10]="ABCEGDF";
	struct Stu s[3] = { {"zhangsan", 30},{"lisi", 34},{"wangwu", 20} };
	int sz=sizeof(s)/sizeof(s[0]);
	qsort(arr1,sz,sizeof(s[0]),cmp_char);
	// for(int i=0;i<sz;i++)
	// {
	// 		printf("%d ",arr[i]);
	// }
	printf("%s\\n", arr1);
	
	return 0;
}

compare函数

int类型比较


int cmp_int(const void*e1,const void*e2)
{
	return *(int*)e1-*(int*)e2;
}

char类型比较

int cmp_char(const void*e1,const void*e2)
{
	return *(char*)e1-*(char*)e2;
	//return strcmp((char*)e1,(char*)e2);
}

double类型比较
注意:在对浮点或者double型的一定要用三目运算符,因为要是使用像整型那样相减的话,如果是两个很接近的数则可能返回一个很小的小数(大于-1,小于1),而cmp的返回值是int型,因此会将这个小数返回0,系统认为是相等,失去了本来存在的大小关系(转载)

int cmp_char(const void*e1,const void*e2)
{
	return *(char*)e1 > *(char*)e2 ? 1 : -1;
}

按结构体年龄(int)

int sort_by_age(const void* e1, const void* e2)
{
	return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}

按结构体名字(字符串)

int sort_by_name(const void*e1, const void*e2)
{
	return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}

自己模拟实现qsort函数

模拟实现冒泡qsort函数

void bubble_qsort(void* base, 
					int sz, 
					int width ,
					int (*cmp)(const void*e1, const void*e2)
					)
{
	for (int i = 0; i < sz-1; ++i)//趟数
	{
		for (int j = 0; j < sz-i-1; ++j)
		{
			if(cmp((char*)base+j*width, (char*)base+(j+1)*width)>0)//判断函数返回值
			{
				swap((char*)base+j*width, (char*)base+(j+1)*width,width);
				//转换类型为char* 方便与width结合使用 第j和第j+1个调换
			}
		}
	}
}

交换函数

void swap(char*buffer1,char*bufffer2,int width)
{
	for(int i=0;i<width;i++)//由于是char* width限制按字节交换
	{
		char tmp=*buffer1;
		*buffer1=*bufffer2;
		*bufffer2=tmp;
		buffer1++;
		bufffer2++;
	}
}

以上是关于C语言--回调函数实列 模拟qsort函数的主要内容,如果未能解决你的问题,请参考以下文章

C语言qsort()库函数用回调函数的原因

爆肝!回调函数的实用案例,建议收藏~(计算器改良,qsort快排函数应用实例,冒泡函数核心理解,模拟qsort函数)

c语言重要库函数解读 和模拟实现————Qsort

C*指针进阶

C语言之qsort函数进行排序

模拟实现qsort atoi函数,小白快来看