qsort函数快速排序

qsort 函数介绍

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

其函数原型:
void qsort( void *base,
size_t num,
size_t width,
int (__cdecl *compare )(const void *elem1, const void *elem2 ) );

*其参数:
base-- 指向要排序的数组的第一个元素的指针。
size_t num-- 由 base 指向的数组中元素的个数。
size_t width :数组中每个元素的大小(以字节为单位)是无符号整型。
compar:用来比较两个元素的函数,即函数指针(回调函数)。

回调函数:

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

compar参数:
------compar参数指向一个比较两个元素的函数:

1.重复调用此函数以比较两个元素,
2.如果compar返回值小于0(< 0),那么p1所指向元素会被排在p2所指向元素的左面;
3.如果compar返回值等于0(= 0),那么p1所指向元素与p2所指向元素的顺序不确定;
4.如果compar返回值大于0(> 0),那么p1所指向元素会被排在p2所指向元素的右面。

返回值
qsort函数没有返回值;

其所含头文件:<stdlib.h>

简单可以理解为:

  1. int compar (const void* p1, const void* p2);
  2. qsort ( arr , n , sizeof ( arr[0] ) , compar );

举个例子说:

当对一个长度为1000的数组进行排序,且数组类型 int。

qsort(arr,1000,sizeof (int),cmpar);
//其中对于cmpar写成:
cmpar(const void *a, const void *b)
{
return *(int*)a-*(int *)b;//有小至大的排序
//return *(int *)b - *(int *)a; 由大至小排序
}

  • 想要熟练运用qsort函数,首先要熟悉其含的参数;

下面我们来熟悉使用qsort函数吧

int main()
{
    
    
	int n = 0;
	printf("请输入一串数组的个数:");
	scanf("%d",&n);
	int arr[100] = {
    
     0 };

	int i = 0;
	for (i = 0; i < n; i++)
	{
    
    
		scanf("%d", &arr[i]);
	}

	qsort(arr,n,sizeof arr[0],compar);

	for (i = 0; i < n; i++)
	{
    
    
		printf("%d ", arr[i]);
	}

	return 0;
}

还有compar函数:

int cmp(const void* e1, const void* e2)
{
    
    
    //由从小到大的顺序排列
	return *(int*)e1 - *(int*)e2;
}

自主实现qsort函数

1. 对于整形数组的排列

#include <stdio.h>

void swp(char* b1, char* b2,int width)
{
    
    
	int i = 0;
	for (i = 0; i < width; i++)
	{
    
    
		int tmp = *b1;
		*b1 = *b2;
		*b2 = tmp;
		b1++;
		b2++;
	}
}

int cmpar(const void* a, const void* b)
{
    
    
    //由从小到大的顺序排列
	return *(int*)a - *(int*)b;
}

void my_qsort(void* base, int sz, int width, int (*cmp)( const void* e1, const void* e2))
{
    
    
	int i = 0;
	for (i = 0; i < sz-1; i++)
	{
    
    //每一趟
		int j = 0;
		for (j = 0; j < sz-1 - i; j++)
		{
    
    
			//交换
			if (cmpar((char*)base+j*width,(char*)base+(1+j)*width) > 0)
			{
    
    
				//进行交换
				swp((char*)base + j * width, (char*)base + (1 + j) * width,width);
			}
		}
	}
}

int main()
{
    
    
	int arr[1000] = {
    
     0 };
	int n = 0;
	scanf("%d", &n);
	int i = 0;
	for (i = 0; i < n; i++)
	{
    
    
		scanf("%d", &arr[i]);
	}

	my_qsort(arr,n,sizeof arr[0],cmpar);

	for (i = 0; i < n; i++)
	{
    
    
		printf("%d ", arr[i]);
	}

	return 0;
}


2 .对于浮点数类型数组的排序

只需要将 cmpar 的内容中强制类型转换变成(float * )就可以

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

同样的道理双浮点数类型的排序也是如此:

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

结构体类型的排序:

//定义一个结构体
struct Book
{
    
    
	char name[20];
	int price;
	int date;
};
int main()
{
    
    
	//声明结构体
	struct Book b1[3] = {
    
     {
    
    "shuihuzhuan", 23,1987} ,{
    
    "sunwukong",32,2000},{
    
    "sanguoyanyi",45,2003}, };
	int sz = sizeof b1 / sizeof(b1[0]);
	my_qsort(b1, sz, sizeof(b1[0]), cmpar);

	return 0;
}
int cmpar(const void * s1, const void * s2)
{
    
    
    int ret=((struct Book*)s1)->price - ((struct Book*)s2)->price;
	return ret;
}
void my_qsort(void* base, int sz, int width, int (*cmp)( const void* e1, const void* e2))
{
    
    
	int i = 0;
	for (i = 0; i < sz-1; i++)
	{
    
    //每一趟
		int j = 0;
		for (j = 0; j < sz-1 - i; j++)
		{
    
    
			//交换
			if (cmpar((char*)base+j*width,(char*)base+(1+j)*width) > 0)
			{
    
    
				//进行交换
				swp((char*)base + j * width, (char*)base + (1 + j) * width,width);
			}
		}
	}
}

其他的类型也可以以类似的方式写出,其他的我就不写了,大家加油吧!

猜你喜欢

转载自blog.csdn.net/m0_66780695/article/details/131149725