网站首页 > 技术文章 正文
我们知道,数组排序中的“快速排序”有较高的时间效率,为此C函数库stdlib提供了此函数,并能够对整形、浮点型、字符串及至结构体中的某个关键字实现排序。我们知道,C语言是强类型语言,且没有C++的函数重载和模板机制,那怎样实现这种类型泛化的操作呢?C用void*指针和函数指针实现回调函数来达成。这也是此函数的参数看起来特别复杂的原因:
void qsort( void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*))
void *base:类型为void*,相当于泛型,指向要排序的数组的第一个元素的指针。
nitems:数组中元素的个数,在数组指针中无法内含元素个数,需要另外的参数提供。
size:因为数据指针提供的是void*类型,需要另外的参数来提供数组中每个元素的大小,以字节为单位。
int compar(const void *p1, const void *p2);
compar是一个函数指针,注意函数参数的类型是void*,可以是各种基本类型、字符串、结构体的某个关键字,用来比较两个元素的函数,即函数指针(回调函数)
如果compar返回值小于0(< 0),那么p1所指向元素会被排在p2所指向元素的前面;
如果compar返回值等于0(= 0),那么p1所指向元素与p2所指向元素的顺序不确定;
如果compar返回值大于0(> 0),那么p1所指向元素会被排在p2所指向元素的后面。
实例:
#include <stdio.h>
#include <stdlib.h>
#define NUM 40
void fillarray(double ar[], int n);
void showarray(const double ar[], int n);
int mycomp(const void * p1, const void * p2);
int main(void)
{
double vals[NUM];
fillarray(vals, NUM);
puts("Random list:");
showarray(vals, NUM);
qsort(vals, NUM, sizeof(double), mycomp);
puts("\nSorted list:");
showarray(vals, NUM);
system("pause");
return 0;
}
void fillarray(double ar[], int n)
{
int index;
for( index = 0; index < n; index++)
ar[index] = (double)rand()/((double) rand() + 0.1);
}
void showarray(const double ar[], int n)
{
int index;
for( index = 0; index < n; index++)
{
printf("%9.4f ", ar[index]);
if (index % 6 == 5)
putchar('\n');
}
if (index % 6 != 0)
putchar('\n');
}
/* sort by increasing value */
int mycomp(const void * p1, const void * p2)
{
/* need to use pointers to double to access values */
const double * a1 = (const double *) p1;
const double * a2 = (const double *) p2;
return *(int*)a-*(int*)b;
if (*a1 < *a2)
return -1;
else if (*a1 == *a2)
return 0;
else
return 1;
}
各种类型回调函数的写法
1 整形
int comp(const void*a,const void*b)
{
return *(int*)a-*(int*)b;//由小到大排序
//return *(int *)b - *(int *)a; 为由大到小排序。
}
2 浮点型
int mycomp(const void * p1, const void * p2)
{
const double * a1 = (const double *) p1;
const double * a2 = (const double *) p2;
return *(int*)a-*(int*)b;
if (*a1 < *a2)
return -1;
else if (*a1 == *a2)
return 0;
else
return 1;
}
3 对一个整型二维数组按行的第一个元素进行排序,要求整行一起移动交换。
qsort(a,1000,sizeof(int)*2,comp);//两列
int comp(const void*a,const void*b)
{
return((int*)a)[0]-((int*)b)[0];
}
4 字符串
int Comp(const void*p1,const void*p2)
{
return strcmp((char*)p2,(char*)p1);
}
5 按结构体中某个关键字排序
structNode
{
double data;
int other;
}s[100];
int Comp(constvoid*p1,constvoid*p2)
{
return(*(Node*)p2).data>(*(Node*)p1).data?1:-1;
}
5 按结构体中多个关键字排序(对结构体多级排序)[以二级为例]
struct Node
{
int x;
int y;
}s[100];
//按照x从小到大排序,当x相等时按y从大到小排序
int Comp(const void*p1,const void*p2)
{
struct Node*c=(Node*)p1;
struct Node*d=(Node*)p2;
if(c->x!=d->x) returnc->x-d->x;
else return d->y-c->y;
}
6 对结构体中字符串进行排序
struct Node
{
int data;
char str[100];
}s[100];
//按照结构体中字符串str的字典序排序
int Comp(const void*p1,const void*p2)
{
return strcmp((*(Node*)p1).str,(*(Node*)p2).str);
}
qsort(s,100,sizeof(s[0]),Comp);
-End-
猜你喜欢
- 2024-10-26 C语言、嵌入式项目中一些常用知识及技巧第一弹
- 2024-10-26 C语言编程:最常见 7 道C语言面试题,还是有不少人弄不明白?
- 2024-10-26 初识C语言:简介、环境搭建、第一个HelloWorld
- 2024-10-26 C|volatile关键字使用细节及适用场合
- 2024-10-26 C语言干货:函数知识详解(变量的作用域,全局变量,静态变量)
- 2024-10-26 小白入门C语言20问20答2(新手c语言)
- 2024-10-26 C语言的简单了解及学习2(c语言的入门知识)
- 2024-10-26 C 语言基本语法(c语言的基础语法)
- 2024-10-26 C语言数据怎么描述?最全面解析,C语言基础教学档案!编号零零五
- 2024-10-26 C语言void关键字的高级玩法,6个样例代码告诉你
- 最近发表
-
- 聊一下 gRPC 的 C++ 异步编程_grpc 异步流模式
- [原创首发]安全日志管理中心实战(3)——开源NIDS之suricata部署
- 超详细手把手搭建在ubuntu系统的FFmpeg环境
- Nginx运维之路(Docker多段构建新版本并增加第三方模
- 92.1K小星星,一款开源免费的远程桌面,让你告别付费远程控制!
- Go 人脸识别教程_piwigo人脸识别
- 安卓手机安装Termux——搭建移动服务器
- ubuntu 安装开发环境(c/c++ 15)_ubuntu安装c++编译器
- Rust开发环境搭建指南:从安装到镜像配置的零坑实践
- Windows系统安装VirtualBox构造本地Linux开发环境
- 标签列表
-
- cmd/c (90)
- c++中::是什么意思 (84)
- 标签用于 (71)
- 主键只能有一个吗 (77)
- c#console.writeline不显示 (95)
- pythoncase语句 (88)
- es6includes (74)
- sqlset (76)
- apt-getinstall-y (100)
- node_modules怎么生成 (87)
- chromepost (71)
- flexdirection (73)
- c++int转char (80)
- mysqlany_value (79)
- static函数和普通函数 (84)
- el-date-picker开始日期早于结束日期 (76)
- js判断是否是json字符串 (75)
- c语言min函数头文件 (77)
- asynccallback (87)
- localstorage.removeitem (77)
- vector线程安全吗 (73)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- 无效的列索引 (74)
