qsort()函数用法
功能:该函数为库函数,使用快速排序例程进行排序。
头文件:#include
原型:void qsort(void *base, int nelem, int width, int (*fcmp)(const void *,const void *))
参数: 1.待排序数组首地址
2.数组中待排序的元素个数
3.个元素的所占空间的大小
4.指向函数的指针,用于确定排序的顺序
qsort可对各类数组进行排序,主要分为七大类。qsort要求提供一个比较函数(即第四个参数函数指针),是为了做到通用性更好一些。
以下是对各类的讨论(本文默认排序都是有小到大,若需从大到小可改变函数指针两参数的顺序):
一、对int类型数组排序:
int num[100];
需要自己构造的判断函数:
int cmp ( const void *a , const void *b)
{
return *(int *)a - *(int *)b; //顺序有小到大,如需从大到小将两数字颠倒运算
}
调用库函数qsort:
qsort(num, 100 ,sizeof(num[0]), cmp);
二、对char类型数组排序:
char s[100];
需要自己构造的判断函数:
int cmp ( const void *a , const void *b)
{
return *(char *)a - *(char *)b;
}
调用库函数qsort:
qsort(s, 100 ,sizeof(s[0]), cmp);
三、对double类型数组排序:
double num[100];
需要自己构造的判断函数:
int cmp ( const void *a , const void *b)
{
return *(double *)a > *(double *)b ? 1 : -1; //特别注意!!!
}
调用库函数qsort:
qsort(num, 100 ,sizeof(num[0]), cmp);
四、对结构体一级排序:
struct In{
double data;
int other;
}s[100];
需要自己构造的判断函数:
int cmp ( const void *a , const void *b)
{
return (*(struct In *)a).data > (*(struct In *)b).data ? 1 : -1; //特别注意!!!
}
调用库函数qsort:
qsort(s, 100 ,sizeof(s[0]), cmp);
五、对结构体二级排序:
struct In{
int x;
int y;
}s[100]; //按照 x 从小到大排序, x 相等的时候按照 y 从大到小排序
需要自己构造的判断函数:
int cmp ( const void *a , const void *b)
{
struct In * c = (In *)a;
struct In * d = (In *)b;
if ( c-> x != d-> x )
return c-> x - d-> x ;
else
return d-> y - c-> y ;
}
调用库函数qsort:
qsort(s, 100 ,sizeof(s[0]), cmp);
六、对字符串进行排序:
struct In{
int x;
char str[100];
}s[100]; //按照结构体中字符串str的字典的顺序进行排序
需要自己构造的判断函数:
int cmp ( const void *a , const void *b)
{
return strcmp( (*(struct In *)a).str > (*(struct In *)b).str );
}
调用库函数qsort:
qsort(s, 100 ,sizeof(s[0]), cmp);
七、计算几何中求凸包的cmp
int cmp( const void* a, const void* b) //重点是cmp函数,把除了1点以外的所有点,旋转角度排序
{
struct point *c = (point *)a;
struct point *d = (point *)b;
if ( calc(*c, *d, p[1]) < 0)
return 1;
else if ( !calc(*c, *d, p[1]) && dis(c->x, c->y, p[1].y ) < dis(d->x, d->y, p[1].x, p[1].y )) //如果在一条直线上,则把远的放在前面
return 1;
else
return -1;
}
具体应用:
下面是我使用qsort排序一个整型数组,一个浮点型数组,一个字符串数组的例子:
#include
#include
typedef struct In{
int data;
char str[100];
}s[5];
int cmp_int(const void *a, const void *b) //由大到小排序
{
return *(int*)a - *(int*)b;
}
int cmp_double(const void *a, const void *b) //由大到小排序
{
return *(double*)a > *(double*)b ? 1 : -1;
}
int cmp_str(const void *a, const void *b) //用char**对字符串数组进行排序
{
return strcmp(*(char**)a, *(char**)b);
}
int cmp_str2(const void *a, const void *b) //用结构体对字符串数组进行排序
{
return strcmp((*(struct In*)a).str, (*(struct In*)b).str);
}
int main()
{
int i = 0;
int arr1[10] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 10 };
double arr2[10] = { 6.2, 8.4, 5.2, 9.5, 4.3, 2.1, 7.4, 0.1, 5.5, 6.6 };
char* str[5] = { "mno", "def", "abc", "ghi", "jkl" };
struct In s[5] = { { 1, "mno" }, { 2, "def" }, { 3, "abc" }, { 4, "ghi" }, { 5, "jkl" } };
qsort(arr1, 10, sizeof(int), cmp_int); //对整数数组排序
qsort(arr2, 10, sizeof(double), cmp_double); //对浮点型数组排序
qsort(str, 5, sizeof(char*), cmp_str); //对结构体字符串进行排序(方法1)
qsort(s, 5, sizeof(s[0]), cmp_str2); //对结构体字符串进行排序(方法2)
for (i = 0; i<10; i++)
{
printf("%d ", arr1[i]);
}
printf("\n");
for (i = 0; i<10; i++)
{
printf("%.1lf ", arr2[i]);
}
printf("\n");
for (i = 0; i<5; i++) //用char**对字符串数组进行排序打印
{
printf("%s ", str[i]);
}
printf("\n");
for (i = 0; i<5; i++) //用结构体对字符串数组进行排序打印
{
printf("%s ", s[i].str);
}
return 0;
}