简单介绍一下qsort函数

目录

一.回调函数

二.qsort函数

三.void*指针

四.用qsort函数进行升序排序

1.整形数组排序

2.结构体数组排序

 3.字符数组排序

五.使用冒泡排序模拟实现qsort函数


一.回调函数

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个
函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数
的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进
行响应。

二.qsort函数

qsort是一个函数,基于快速排序算法实现的一个排序函数。

这是MSDN上面的介绍:

简单介绍一下qsort函数_第1张图片

void qsort(void* base,       //待排序数据的起始位置
          size_t num,         //数组的元素个数
          size_t width,       //一个元素的字节大小
     int(*cmp)(const void* elem1, const void* elem2)//cmp是一个函数指针,指向一个比较函数,需 
                                               //要自己编写,elem1,elem2是两个待比较元素的地址

   返回值大小     简单介绍一下qsort函数_第2张图片    注意:排序整形数据可以用> <,但排序结构体数据可能不方便用> <比较了。

三.void*指针

 相当于通用的指针类型,可以存放指向任何类型的指针,当你的函数参数类型不确定时,可以使用 void *,不能解引用和+-整数运算。

四.用qsort函数进行升序排序

1.整形数组排序

int i_cmp (const void* e1, const void* e2)          //qsort默认升序排序,想要降序排序只需要调                                                                              
                                                                          换e1和e2即可
{
	return *((int*)e1) - *((int*)e2);     //void*指针不能解引用,需要强制类型转换为int*型
}
void print(int arr[], int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
}
int main()
{
	int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]), i_cmp);
	print(arr, sz);
	return 0;
}

2.结构体数组排序

struct Stu
{
	char name[20];
	int age;
    double score;
};
int j_cmp_by_age(const void* e1, const void* e2)
{
	return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
//int j_cmp_by_name(const void*e1,const void* e2)
//{
//    return strcmp( ((struct Stu*)e1)->name , ((struct Stu*)e2)->name)  //字符串比较大小要使 
                                                                              用strcmp函数
//}
int main()
{
	struct	Stu stu[3] = { {"lisi",20,70.2},{"wangwu",23,88.5},{"zhangsan",18,90.2}};
	int sz = sizeof(stu) / sizeof(stu[0]);
	qsort(stu, sz, sizeof(stu[0]), j_cmp_by_age);   //通过年龄来排序
    //qsort(stu,sz,sizeof(stu[0]), j_cmp_by_name);   //通过姓名来排序
	printf("%s %d\n", stu[0].name, stu[0].age);
	printf("%s %d\n", stu[1].name, stu[1].age);
	printf("%s %d\n", stu[2].name, stu[2].age);
	return 0;
}

 strcmp返回值大小和qsort函数返回值恰好一样,srtcmp函数比较2个字符串大小,一个字符一个字符进行比较,按ASCII值比较大小。简单介绍一下qsort函数_第3张图片

 3.字符数组排序

int f_cmp(const void* e1, const void* e2)
{
	return *((char*)e1) - *((char*)e2);
}
void print(char arr[], int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%c ",arr[i]);
	}
}
int main()
{
	char arr[] = "dfesagc";
	int sz = strlen(arr);
	qsort(arr, sz, sizeof(arr[0]), f_cmp);
	print(arr, sz);
	return 0;
}

五.使用冒泡排序模拟实现qsort函数

int cmp(const void* e1, const void* e2)
{
	return *(int*)e1 - *(int*)e2;                         
}
void Swap(char* buff1, char* buff2, int width)
{
	int i = 0;
	for (i = 0; i < width; i++)
	{
		char tmp = *buff1;
		*buff1 = *buff2;
		*buff2 = tmp;
		buff1++;
		buff2++;
	}
}
//因为交换的时候是传地址,所以要知道元素的宽度,一个字节一个字节的交换 ,这样也证明了使用char*指 
 //针的好处!
void bubble_sort(void* base, int num, int width, int (*cmp)(void* e1, void* e2))
{
	int i = 0;
	for (i = 0; i < num - 1; i++)       //趟数
	{
		int j = 0;
		for (j = 0; j < num - 1 - i; j++)
		{
			if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0)  
               //升序排序
               //j = 0时,比较的是第一个元素和第二个元素
               // j = 1时,比较的是第二个元素和第三个元素
			{
					Swap((char*)base + j * width, (char*)base + (j + 1) * width, width); 
                                                                          //交换
			}
		}
	}
}
void test()
{
	int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	bubble_sort(arr, sz, sizeof(arr[0]), cmp);
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
}
int main()
{
	test();
	return 0;
}

你可能感兴趣的