目录
1.qsort函数的介绍
qsort函数能够排序任意数据类型的数组,如整形、浮点型、字符串以及结构体类型。
qsort函数是库函数,在使用时应包含对应的头文件(#include<stdlib.h>)
2.qsort函数的声明
void qsort(void *base, size_t num, size_t width, int ( *compare)(const void *elem1,const void *elem2));
void *base:需要排序的数组的首元素的地址
size_t num:数组的元素个数
size_t width:数组元素的大小(所占字节数)
int (*compare)(const void* elem1, const void* elem2):该参数为函数指针,指向一个比较函数,在排序时,用来比较两个元素大小。两个参数(elem1, elem2)为所比较元素的地址,参数类型为void*,因此可以接收任意类型的参数。
返回类型为Int,elem1 < elem2时,返回<0的值;elem1 = elem2时,返回0;elem1 > elem2时,返回>0的值(此时排序为升序,若想将排序改为降序,只需在elem1 < elem2时返回>0的值,elem1 > elem2时,返回<0的值)
3.qsort函数的使用
1.整形
首先实现比较函数(cmp_int)
int cmp_int(const void* p1, const void* p2)
{
return (*((int*)p1)) - (*(int*)p2);
}
首先将指针强制类型转换为整形指针,再进行解引用获得元素的值,最后返回两个元素的差值。
再调用qsort函数
#include <stdio.h>
#include <stdlib.h>
int cmp_int(const void* p1, const void* p2)
{
return (*((int*)p1)) - (*(int*)p2);
}
void test1()
{
int arr[] = { 1,2,10,4,11,6,7,9,0 };
int sz = sizeof(arr) / sizeof(arr[0]);
printf("排序前: ");
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
qsort(arr, sz, sizeof(arr[0]), cmp_int);
printf("排序后: ");
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int main()
{
test1();
return 0;
}
排序结果
2.浮点型
首先实现比较函数cmp_double
double为8字节,若直接返回两个元素的差值,此时强制类型转换为int,浮点类型不完整,则可能出现错误
如
因此在处理时使用if else语句判断
int cmp_double(const void* p1, const void* p2)
{
double ret = *(double*)p1 - *(double*)p2;
if (ret > 0)
return 1;
else if (ret < 0)
return -1;
else
return 0;
}
再调用qsort函数
#include <stdio.h>
#include <stdlib.h>
int cmp_double(const void* p1, const void* p2)
{
double ret = *(double*)p1 - *(double*)p2;
if (ret > 0)
return 1;
else if (ret < 0)
return -1;
else
return 0;
}
void test2()
{
double arr[] = { 1.3,3,2.1,0.9,1.7,10.3,9.1 };
int sz = sizeof(arr) / sizeof(arr[0]);
printf("排序前:");
for (int i = 0; i < sz; i++)
{
printf("%.2lf ", arr[i]);
}
printf("\n");
qsort(arr, sz, sizeof(arr[0]), cmp_double);
printf("排序后:");
for (int i = 0; i < sz; i++)
{
printf("%.2lf ", arr[i]);
}
printf("\n");
}
int main()
{
test2();
return 0;
}
排序结果
3.结构体类型
在对结构体类型进行排序时,首先要确定排序的依据
如结构体
struct stu
{
int age;
char name[10];
double score;
};
首先确定是依据年龄、姓名还是分数进行排序,或是进行多级排序,即先按分数排序,若分数相同,则按姓名排序。
(1)一级排序
按姓名进行排序
比较函数cmp_by_name
使用strcmp函数比较两个字符串的大小
int cmp_stu_by_name(const void* p1,const void* p2)
{
return (strcmp(((struct stu*)p1)->name , ((struct stu*)p2)->name ));
}
调用qsort函数
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct stu
{
int age;
char name[10];
double score;
};
int cmp_stu_by_name(const void* p1,const void* p2)
{
return (strcmp(((struct stu*)p1)->name , ((struct stu*)p2)->name ));
}
void test3()
{
struct stu students[3] = { {12,"li",90.5},{11,"zhang",80.3},{10,"wang",97.6} };
int sz = sizeof(students) / sizeof(students[0]);
printf("排序前:\n");
for (int i = 0; i < sz; i++)
{
printf("%d %s %.2lf", students[i].age, students[i].name, students[i].score);
printf("\n");
}
printf("\n");
qsort(students, sz, sizeof(students[0]), cmp_stu_by_name);//按名字排序
printf("排序后:\n");
for (int i = 0; i < sz; i++)
{
printf("%d %s %.2lf", students[i].age, students[i].name, students[i].score);
printf("\n");
}
printf("\n");
}
int main()
{
test3();
return 0;
}
排序结果
(2)多级排序
先按照成绩排序,若成绩相同,则按照名字排序
比较函数cmp_stu
int cmp_stu(const void* p1, const void* p2)
{
double ret = ((struct stu*)p2)->score - ((struct stu*)p1)->score;
if (ret > 0)
return 1;
else if (ret < 0)
return -1;
else
return (strcmp(((struct stu*)p1)->name, ((struct stu*)p2)->name));
}
在成绩相同时,按照名字进行排序,若还要按照年龄排序,在名字相同时,按照年龄排序即可。
调用qsort函数
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct stu
{
int age;
char name[10];
double score;
};
int cmp_stu(const void* p1, const void* p2)
{
double ret = ((struct stu*)p2)->score - ((struct stu*)p1)->score;
if (ret > 0)
return 1;
else if (ret < 0)
return -1;
else
return (strcmp(((struct stu*)p1)->name, ((struct stu*)p2)->name));
}
void test3()
{
struct stu students[] = { {12,"li",90.5},{11,"zhang",80.3},{10,"wang",97.6},{12,"zhao",80.3} };
int sz = sizeof(students) / sizeof(students[0]);
printf("排序前:\n");
for (int i = 0; i < sz; i++)
{
printf("%d %s %.2lf", students[i].age, students[i].name, students[i].score);
printf("\n");
}
printf("\n");
qsort(students, sz, sizeof(students[0]), cmp_stu);
printf("排序后:\n");
for (int i = 0; i < sz; i++)
{
printf("%d %s %.2lf", students[i].age, students[i].name, students[i].score);
printf("\n");
}
printf("\n");
}
int main()
{
test3();
return 0;
}
排序结果