qsort:任意类型数据的排序

qsort,头文件stdlib.h

函数原型

void qsort (void * base,size_t num,size_t size,int (*compare)(const void * a,const void * b));

base——接收待排序的任意类型的数组的首地址。

size_t——本质就是个int.

num——数组元素的个数。

size——数组每个元素的大小。

int(*compare)(const void* a,const void* a)——函数指针,指向比较函数,compare是函数指针变量

void* 类型的指针 可以接收任意类型的元素地址,让qsort可以排序任意类型数据的关键。

void* 类型的指针 不能进行解引用操作。

void* 类型的指针 不能进行加减整数的操作

函数使用

在比较函数中比较传过来的ab的值如果a的值大于b则返回正数,a == b则返回0,a小于b则返回负数,qsort根据比较函数返回的值进行排序进行排序。

int compare(const void* a,const void* b)//接收传过来的任意两个类型的元素地址
{
	int *pa = (int*)a;//待排序的是个整形数组,将形式参数ab强制转换
	int *pb = (int*)b;

	return (*pa) - (*pb);//如果a的值比b的值大则返回正数,相等则返回0,a < b则返回负数
}

函数的返回类型只能是int

函数调用 

int arr[] = {1,89,4,8,3,46,87,64,56};

int sz = sizeof(arr)/sizeof(arr[0]);

 qsort(arr,sz,sizeof,compare);

使用实例

整形排序

#include <stdio.h>
#include <stdlib.h>

int compare(const void* a,const void* b)//接收传过来的任意两个类型的元素地址
{
	int *pa = (int*)a;//待排序的是个整形数组,将形式参数ab强制转换
	int *pb = (int*)b;

	return (*pa) - (*pb);//如果a的值比b的值大则返回正数,相等则返回0,a < b则返回负数
}

int main()
{
	int arr[]= {58,9,4,6,9,4,3,7,6,4};
	int sz = sizeof(arr)/sizeof(arr[0]);
	
	qsort(arr,sz,sizeof(int),compare);//将传过来的数进行排序

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

	return 0;
}

当前实现的是升序排序,假如要实现降序排序,将pa和pb互换即可。 

浮点型排序

#include <stdio.h>
#include <stdlib.h>

int compare(const void* a,const void* b)
{
	float* pa = (float*)a;
	float* pb = (float*)b;

	//return (*pa) - (*pb);两个数相减是个浮点数,要返回的是个int会导致类型冲突
	if((*pa) > (*pb))
	{
		return 1;
	}
	else if((*pa) < (*pb))
	{
		return -1;
	}
	else
	{
		return 0;
	}
}

void test1()
{
	float f[] = {2.0,1.5,3.5,4.2,3.3,8.5,9.0,10.4,20.3};
	int sz = sizeof(f)/sizeof(f[0]);
	qsort(f,sz,sizeof(f[0]),compare);

	int i;

	for(i = 0;i < sz;i++)
	{
		printf("%f \n",f[i]);
	}
}

int main()
{
	test1();
	
	return 0;
}

结构体排序

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


struct stu
{
	char name[20];
	int age;
};
int cmp_by_age(const void* a,const void* b)
{
	return ((struct stu*)a) -> age - ((struct stu*)b) -> age;//访问结构体数组中的元素ab中的年龄成员
}
int cmp_by_name(const void* a,const void*b)
{
	return strcmp(((struct stu*)a)-> name,((struct stu*)b) -> name);//比较名字就是比较两个字符串
	//比较三个名字的首字母的Ascll值
}
void test3()
{
	struct stu s[3] = {{"zhangsan",20},{"lisi",19},{"wangwu",18}};
	int sz = sizeof(s)/sizeof(s[0]);

	//qsort(s,sz,sizeof(s[0]),cmp_bt_age);对结构体中的年龄成员进行排序
	qsort(s,sz,sizeof(s[0]),cmp_by_name);//对姓名成员进行排序

	int i;
		
	for(i = 0;i < sz;i++)
	{
		printf("%s ",s[i].name);
	}
	putchar('\n');
}

int main()
{
	test3();

	return 0;
}

 结构体比较是对结构体内的成员进行比较,而不是对整个结构体进行比较。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值