你应该知道的C语言干货(6)(qsort详解及模拟实现)

我们知道包含stdlib.h头文件后,就可以使用qsort这个库函数,接下来让我们了解他。

 

目录

        #qsort 函数介绍及举例使用

        #qsort函数模拟实现

#下期预告


#qsort 函数介绍及举例使用

 

qsort第一个参数是要排序的数组的首地址,第二个参数是要排序的数据数量,有几个,第三个参数是要排序的那个参数占几个字节,最后一个参数是函数指针,是让用户进行使用的函数,可以让用户对任意类型数据进行排序,一会儿我们会说到。

 快速排序,可以实现像冒泡排序等的排序,同时能够对结构体排序时,将其其他数据一同排序,这是他的一大优点,接下来看举例:

#include 
#include 
#include 

typedef struct Qsort
{
	char name[8];
	int age;
}Qsort;

int cmp(void* p1, void* p2)
{
	return ((Qsort*)p1)->age - ((Qsort*)p2)->age;
}

int main()
{

	Qsort People[3];
	memset(People, 0, sizeof(Qsort) * 3);

	for (int i = 0; i < 3; i++)
	{
		scanf("%s %d", People[i].name, &People[i].age);
		getchar();
	}

	qsort(People,3,sizeof(Qsort), cmp);
	
	for (int i = 0; i < 3; i++)
	{
		printf("%s %d\n", People[i].name, People[i].age);
	}

	return 0;
}

运行截图如下:

你应该知道的C语言干货(6)(qsort详解及模拟实现)_第1张图片

实现了年龄的排序,同时将名字也进行了移动,非常好用,接下来再举几个例子: 

 

Example 1:对整数排序

#include 
#include 

int cmp(const void* a, const void* b)
{
	return *(int*)a - *(int*)b;
}

int main()
{

	int arr[10] = { 1,2,3,7,3,1,5,9,2,5 };
	qsort(arr, 10, sizeof(int), cmp);
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}

	return 0;
}

你应该知道的C语言干货(6)(qsort详解及模拟实现)_第2张图片

 

Example 2:对浮点数排序

#include 
#include 

int cmp(const void* a, const void* b)
{
	return *(float*)a - *(float*)b;
}

int main()
{

	float farr[5] = { 3.14,5.20,13.14,6.6,11.1 };
	qsort(farr, 5, 4, cmp);
	for (int i = 0; i < 5; i++)
	{
		printf("%.2f\n", farr[i]);
	}

	return 0;
}

 你应该知道的C语言干货(6)(qsort详解及模拟实现)_第3张图片

 

 

Example 3:对名字排序

#include 
#include 
#include 

typedef struct Qsort
{
	char name[8];
	int age;
}Qsort;

int cmp(void* p1, void* p2)
{
	return strcmp(((Qsort*)p1)->name , ((Qsort*)p2)->name);
}

int main()
{

	Qsort People[3];
	memset(People, 0, sizeof(Qsort) * 3);

	for (int i = 0; i < 3; i++)
	{
		scanf("%s %d", People[i].name, &People[i].age);
		getchar();
	}

	qsort(People,3,sizeof(Qsort), cmp);
	
	for (int i = 0; i < 3; i++)
	{
		printf("%s %d\n", People[i].name, People[i].age);
	}

	return 0;
}

你应该知道的C语言干货(6)(qsort详解及模拟实现)_第4张图片

 

 

你学会如何使用qsort了吗?如果还有疑问,接下来在qsort的模拟实现中也许会解答你的疑问惑

 

#qsort函数模拟实现

这里的核心排序我们将使用冒泡排序替代,这里本应该使用快速排序作为核心,但这里不涉及数据结构,就不多做介绍,感兴趣可以自己使用快速排序

#include 
#include 
#include 

typedef struct stu
{
	char name[20];
	int age;
}stu;

int cmp(void* p1, void* p2);
void my_qsort(void* base, size_t num, size_t sz, int (*cmp)(const void*
                                                    ,const void*));
void swap(char* a, char* b, int sz);

int main()

{

	//qsort(base,num,size,cmp)
	stu student[3] = { {"nene",23},{"haha",21},{"miao",22} };
	my_qsort(student, 3, sizeof(stu), cmp);

	for (int i = 0; i < 3; i++)
	{
		printf("%s %d\n", student[i].name, student[i].age);
	}

	return 0;
}

//因为我们不知道要比较的数据是什么类型,所以干脆传viod*类型,这样用户使用时
//想比较什么类型的数据自己强制转换就好,就是用cmp函数,将void*类型的参数强
//制转换成int*等类型,解引用后返回差值,或者是大小,返回的值将作为是否进行
//数据交换的依据。
void my_qsort(void* base, size_t num, size_t sz, int (*cmp)(const void*,
                                                         const void*))
{
	assert(base);  //断言,判断传上来的指针是否为NULL

	for (int i = 0; i < num - 1; i++)
	{
		for (int j = 0; j < num - i - 1; j++)
		{
			if (cmp((char*)base + sz * j, 
                            (char*)base + sz * (j + 1)) > 0)
				swap((char*)base + sz * j,  
                            (char*)base + sz * (j + 1), sz); 
                //在这里,根据cmp的返回值决定是否交换
		}
	}
}

int cmp(void* p1, void* p2)
{
	return strcmp(((stu*)p1)->name, ((stu*)p2)->name);
}

//这个函数我们的参数设置为char*,因为我们依然不知道用户想要排序什么
//类型的数据,但是我们交换时不能用void*,void*可以接受任何类型的数据
//但是他没有大小,不能解引用,所以传上来sz这个大小,然后每个字节进行交换
void swap(char* a, char* b, int sz)
{
	assert(a && b);

	while (sz--)
	{
		char temp = *a;
		*a = *b;
		*b = temp;
		a += 1;
		b += 1;
	}
}

你应该知道的C语言干货(6)(qsort详解及模拟实现)_第5张图片

 

 

#下期预告

指针进阶知识:

1.字符指针

2.指针数组

3.数组指针

4.一维数组传参,一级指针传参,区别

   二维数组传参,二级指针传参,区别

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