轻松模拟实现qsort函数

qsort函数简单介绍

qsort函数C语言编译器函数库自带的排序函数。

是base所指数组进行排序。qsort函数包含在C 标准库 - 中。

函数声明

void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*))

参数

  • base-- 指向要排序的数组的第一个元素的指针。

  • nitems-- 由 base 指向的数组中元素的个数。

  • size-- 数组中每个元素的大小,以字节为单位。

  • compar-- 用来比较两个元素的函数,即函数指针(回调函数)

回调函数:

回调函数就是一个通过函数指针调用的函数。如果把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,就说这是回调函数。

compar参数

compar参数指向一个比较两个元素的函数。比较函数的原型应该像下面这样。注意两个形参必须是const void *型,同时在调用compar 函数(compar实质为函数指针,这里称它所指向的函数也为compar)时,传入的实参也必须转换成const void *型。在compar函数内部会将const void *型转换成实际类型。

int compar(const void *p1, const void *p2);

如果compar返回值小于0(< 0),那么p1所指向元素会被排在p2所指向元素的左面;

如果compar返回值等于0(= 0),那么p1所指向元素与p2所指向元素的顺序不确定;

如果compar返回值大于0(> 0),那么p1所指向元素会被排在p2所指向元素的右面。

轻松模拟实现qsort函数_第1张图片

 模拟实现qsort函数

 这里我们用排int型举个简单例子

话不多说,直接上代码:

struct Stu
{
	char name[20];
	int age;
};
//比较两个int型变量大小
int cmp_int(const void*p1,const void*p2)
{
	return *(int*)p1- *(int*)p2;
}
//比较名字
int cmp_by_name(const void*e1, const void*e2)
{
	return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}
//比较年龄
int cmp_by_age(const void* e1, const void* e2)
{
	return ((struct Stu*)e1)->age -((struct Stu*)e2)->age;
}
//进行交换
//这里为了对不同类型变量进行交换,我们用width变量来确定变量类型,以便更好交换
void Swap(char*p1, char* p2, size_t width)
{
	char tmp;
	int i = 0;
//这里我们逐字节交换
	for (i = 0; i < width; i++)
	{
		tmp = *p1;
		*p1 = *p2;
		*p2 = tmp;
		p1++;
		p2++;
	}
}
//模拟qsort函数
void BubbleSort(void*base,size_t num,size_t width,int (*cmp)(const void*p1,const void*p2))
{
	int i, j;
	for (i = 0; i < num; i++)
	{
		for (j = 0; j < num-1-i; j++)
		{
			if (cmp((char*)base + j * width, (char*)base + (j+1) * width)>0)

			{
				Swap( (char*)base + j * width, (char*)base + (j+1) * width, width );
			}
		}
    }
}
//测试自定义的BubbleSort() 
void test1()
{
	int arr[] = { 1,3,5,7,4,2,6,8,9,10 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	BubbleSort(arr,sz,sizeof(arr[0]),cmp_int);
	for(int i=0;i

那为什么需要进行逐字节交换呢?又为什么先强转char*呢?

  因为不同的数据交换时所需要交换的字节数目不同,为了能够满足不同类型数据交换的要求,我们将每一种类型的数据都强转char*,再将所有数据逐字节交换.

你可能感兴趣的:(c语言)