函数简介
函数声明
void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*))
参数
base-- 指向要排序的数组的第一个元素的指针。
nitems-- 由 base 指向的数组中元素的个数。
size-- 数组中每个元素的大小,以字节为单位。
compar-- 用来比较两个元素的函数,即函数指针(回调函数)
回调函数
回调函数就是一个通过函数指针调用的函数。如果把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,就说这是回调函数。
compar参数
compar参数指向一个比较两个元素的函数。比较函数的原型应该像下面这样。注意两个形参必须是const void *型,同时在调用compar 函数(compar实质为函数指针,这里称它所指向的函数也为compar)时,传入的实参也必须转换成const void *型。在compar函数内部会将const void *型转换成实际类型。
int compar(const void *p1, const void *p2);
如果compar返回值小于0(< 0),那么p1所指向元素会被排在p2所指向元素的左面;
如果compar返回值等于0(= 0),那么p1所指向元素与p2所指向元素的顺序不确定;
如果compar返回值大于0(> 0),那么p1所指向元素会被排在p2所指向元素的右面。
功 能
使用排序例程进行排序。
说明
该函数不返回任何值。
头文件:stdlib.h;
应用示例
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int compare( const void *arg1, const void *arg2 );
int main( int argc, char **argv ) {
int i; /* Eliminate argv[0] from sort: */
argv++; argc--; /* Sort remaining args using Quicksort algorithm: */
qsort( (void *)argv(size_t)argc, sizeof( char * ), compare ); /* Output sorted list: */
for( i = 0; i < argc; ++i )
printf( " %s", argv[i] );
printf( "
" );
}
int compare( const void *arg1, const void *arg2 ) { /* Compare all of both strings: */
return _stricmp( * ( char** ) arg1, * ( char** ) arg2 );
}
用法说明
qsort函数的用法说明如下:
例:qsort(a,1000,sizeof(int),comp);
其中comp函数应写为:
1 2 3 4 | int comp(const void*a,const void*b) { return *(int*)a-*(int*)b; } |
上面是由小到大排序,return *(int *)b - *(int *)a; 为由大到小排序。
以下为compare函数原型 //comp
compare( (void *) & elem1, (void *) & elem2 );
Compare 函数的返回值 | 描述 |
< 0 | elem1将被排在elem2前面 |
0 | elem1 等于 elem2 |
> 0 | elem1 将被排在elem2后面 |
(1)对一维数组的排序实例(从小到大排序):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #include<stdio.h> #include<stdlib.h> int comp(const void*a,const void*b) { return *(int*)a-*(int*)b; } int main() { int i=0; int *array; int n; scanf("%d",&n); array=(int*)malloc(n*sizeof(int)); for(;i<n;i++) { scanf("%d",(array+i)); } qsort(array,n,sizeof(int),comp); for(i=0;i<n;i++) { printf("%d ",array[i]); } return 0; } |
对一个二维数组进行排序:
int a[1000][2]; 其中按照a[0]的大小进行一个整体的排序,其中a[1]必须和a[0]一起移动交换。//即第一行和第二行(a[0]和a[1]分别代表第一行和第二行的首地址)。使用库函数排序的代码量并不比用冒泡排序法小,但速度却快很多。
1 2 3 4 5 6 7 | qsort(a,1000,sizeof(int)*2,comp); int comp(const void*a,const void*b) { return((int*)a)[0]-((int*)b)[0]; } |
(2)对字符串进行排序
1 2 3 4 5 6 7 8 9 10 | int Comp(const void*p1,const void*p2) { return strcmp((char*)p2,(char*)p1); } int main() { char a[MAX1][MAX2]; initial(a); qsort(a,lenth,sizeof(a[0]),Comp); //lenth为数组a的长度 |
(3)按结构体中某个关键字排序(对结构体一级排序):
1 2 3 4 5 6 7 8 9 10 | structNode { double data; int other; }s[100]; int Comp(constvoid*p1,constvoid*p2) { return(*(Node*)p2).data>(*(Node*)p1).data?1:-1; } qsort(s,100,sizeof(s[0]),Comp); |
按结构体中多个关键字排序(对结构体多级排序)[以二级为例]:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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; } |
对结构体中字符串进行排序:
1 2 3 4 5 6 7 8 9 10 11 | 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); |
(4)计算几何中求凸包的Comp
1 2 3 4 5 6 7 8 9 10 11 | int Comp(const void*p1,const void*p2) //重点Comp函数,把除了1点外的所有的点旋转角度排序 { struct point*c=(point*)p1; struct point*d=(point*)p2; if(cacl(*c,*d,p[1])<0) return1; elseif(!cacl(*c,*d,p[1])&&dis(c->x,c->y,p[1].x,p[1].y)<dis(d->x,d->y,p[1].x,p[1].y)) //如果在一条直线上,则把远的放在前面 return1; elsereturn-1; } |