qsort快速排序函数详解

c语言:qsort()函数

先来看一下qsort函数的原型
void qsort( void *base,
size_t num,
size_t width,
int (__cdecl *compare )(const void *elem1, const void *elem2 ) );

qsort()函数需要的头文件#include

是的这函数看起来复杂,如果你一步步来看的话其实就那么回事。

base:待排序的数组
num:数组元素的个数
width:每个元素的大小
compare:这是一个函数指针,指向的是一个来比较相邻两个元素的大小的函数,但这个函数要自己写!

int (__cdecl *compare )(const void *elem1, const void *elem2 ) )
自己实现比较函数,一般是拿两个参数相减返回差值

compare的返回值 实现
>0 elem1被排在elem2后面
<0 elem1被排在elem2前面
=0 位置不发生变化

qsort这个函数到底怎么用呢,我这会举例各种类型的比较函数和各种类型传参
1.整形
2.浮点型
3.字符
4.结构体

先来看整形,

#include 
#include 

int cmp_int(const void* s1, const void* s2)
{//比较整形
	return *(int*)s1 - *(int*)s2;
}

//打印整形数组
void print(int* arr, int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}

int main()
{
	int arr[] = { 9,2,1,3,4,10,5,6,8,7 };
		qsort(arr,
		sizeof(arr) / sizeof(arr[0]),
		sizeof(arr[0]),
		cmp_int);
	print(arr, sizeof(arr) / sizeof(arr[0]));
	
	return 0;
}

字符型

比较字符型这里我用的是strcmp函数,需要#include头文件。
简单说一下strcmp函数是用来比较字符串大小的,从左到右依次比较字符串每个字符的ASCII码值大小,我们这用来比较字符也是每问题的。
恰巧的是strcmp函数的返回值和比较函数是一样的,
s1>s2返回大于0的数
s1 s1==s2返回0
也可以看看->strcmp函数介绍

#include 
#include 

int cmp_char(const void* s1, const void* s2)
{//比较字符型
	return strcmp((char*)s1, (char*)s2);
}

//打印字符数组
void print2(char* arr, int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%c ", arr[i]);
	}
	printf("\n");
}
int main()
{
		char arr2[] = { 'b','c','d','e','a','f','\0' };
		qsort(arr2,
		sizeof(arr2) / sizeof(arr2[0]),
		sizeof(arr2[0]),
		cmp_char);
	print2(arr2, sizeof(arr2) / sizeof(arr2[0]));
	
	return 0;
}

浮点型

#include 
#include 

int cmp_float(const void* s1, const void* s2)
{//比较浮点型
	return *(float*)s1 - *(float*)s2;
}
void print3(float* arr, int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%.1f ", arr[i]);
	}
	printf("\n");

int main()
{
		float arr3[] = { 2.2,1.1,4.4,3.3,9.9,8.8,5.5,6.6,7.7 };
		qsort(arr3,
		sizeof(arr3) / sizeof(arr3[0]),
		sizeof(arr3[0]),
		cmp_float);
	print3(arr3, sizeof(arr3) / sizeof(arr3[0]));
	
	return 0;
}

结构体数组
我简单声明了一个结构,内容是书名和价格
比较函数那里,因为解引用的的优先级要高于强制转换,所以用括号括起来.
我写了两个比较函数,让结构体按分别按名字排序和价格排序。

#include 
#include 

struct book
{
	char name[20];
	int price;
};

int cmp_struct_name(const void* s1, const void* s2)
{//比较结构体,按名字排序
	return  strcmp(((struct book*)s1)->name, ((struct book*)s2)->name);
}

int cmp_struct_price(const void* s1, const void* s2)
{//比较结构体,按价格排序
	return ((struct book*)s1)->price - ((struct book*)s2)->price;
}

//打印结构体数组
void print4(struct book* s1, int sz)
{
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		printf("%s ", s1->name);
		s1++;
	}
	printf("\n");
}
int main()
{
	struct book bk[] = { {"c plus",35},{"java",30},{"html+css",25} };
		//按名字排序
	qsort(bk,
		sizeof(bk) / sizeof(bk[0]),
		sizeof(bk[0]),
		cmp_struct_name);
	print4(bk, sizeof(bk) / sizeof(bk[0]));


	//按价格排序
	qsort(bk,
		sizeof(bk) / sizeof(bk[0]),
		sizeof(bk[0]),
		cmp_struct_price);
	print4(bk, sizeof(bk) / sizeof(bk[0]));
	
	return 0;
}

所有代码的实现效果
qsort快速排序函数详解_第1张图片
当然这里是按升序排列的,如果想按降序排列的话其实很简单,只需要把比较函数返回值那里的两个参数换个位置就可以了。

列如整形想从升序变成降序的话,把s1和s2换个位置就行了

int cmp_int(const void* s1, const void* s2)
{//整形升序
	return *(int*)s1 - *(int*)s2;
}
int cmp_int(const void* s1, const void* s2)
{//整形降序
	return *(int*)s2 - *(int*)s1;
}

如过想了解该函数时怎么实现的,可以看看该函数的模拟实现qsort的模拟实现

你可能感兴趣的:(c++,c语言,快速排序,字符串,指针)