【作者主页】siy2333
【专栏介绍】⌈c语言日寄⌋:这是一个专注于C语言刷题的专栏,精选题目,搭配详细题解、拓展算法。从基础语法到复杂算法,题目涉及的知识点全面覆盖,助力你系统提升。无论你是初学者,还是进阶开发者,这里都能满足你的需求!
【食用方法】1.根据题目自行尝试 2.查看基础思路完善题解 3.学习拓展算法
【Gitee链接】资源保存在我的Gitee仓库:https://gitee.com/siy2333/study
文章目录
- 前言
- 题目引入
- 一、qsort函数的定义与使用
- qsort函数的定义
- qsort函数的使用
- 1. 示例:对整数数组排序
- 2. 示例:对结构体数组排序
- 二、知识点分析
- 1. qsort函数的参数
- base参数
- nitems参数
- size参数
- compar参数
- 2. 比较函数的编写
- 对整数数组排序
- 对浮点数数组排序
- 对字符串数组排序
- 对结构体数组排序
- 3. qsort函数的工作原理
- 三、注意事项
- 1. 比较函数的返回值
- 2. 比较函数的参数类型
- 3. 数组的大小
- 4. 数组的元素个数
- 四、拓展应用
- 1. 对结构体数组进行多级排序
- 2. 对结构体数组进行逆序排序
- 3. 对结构体数组进行部分排序
- 4. 对结构体数组进行自定义排序
- 五、总结
前言
在C语言的世界里,qsort
函数是一个非常强大且灵活的工具,它允许我们对任意类型的数组进行快速排序。这种特性使得 qsort
在处理复杂数据排序时变得非常方便。今天,我们就通过一个简单的程序来深入探讨 qsort
的使用,以及它在C语言中的重要性。
题目引入
下面程序的输出结果是:( )
#include <stdio.h>
#include <stdlib.h>struct stu
{int num;char name[10];int age;
};int cmp(const void* a, const void* b)
{struct stu* pa = (struct stu*)a;struct stu* pb = (struct stu*)b;if (pa->age != pb->age) {return pa->age - pb->age;} else {return strcmp(pa->name, pb->name);}
}void print_students(struct stu* students, int size)
{for (int i = 0; i < size; i++) {printf("Student %d: Num = %d, Name = %s, Age = %d\n", i + 1, students[i].num, students[i].name, students[i].age);}
}int main()
{struct stu students[3] = {{9801, "zhang", 20},{9802, "wang", 19},{9803, "zhao", 18}};printf("Before sorting:\n");print_students(students, 3);qsort(students, 3, sizeof(struct stu), cmp);printf("After sorting:\n");print_students(students, 3);return 0;
}
A. 按编号排序
B. 按姓名排序
C. 按年龄排序,年龄相同按姓名排序
D. 按年龄排序,年龄相同按编号排序
在接下来的文章中,我们会一起把 qsort
的知识与题目结合起来,学习这一知识点。
一、qsort函数的定义与使用
qsort函数的定义
qsort
函数是C语言标准库 <stdlib.h>
中提供的一个通用排序函数,其原型如下:
void qsort(void* base, size_t nitems, size_t size, int (*compar)(const void*, const void*));
base
:指向要排序的数组的首地址。nitems
:数组中元素的个数。size
:数组中每个元素的大小(以字节为单位)。compar
:比较函数的指针,用于定义排序的规则。
qsort函数的使用
1. 示例:对整数数组排序
#include <stdio.h>
#include <stdlib.h>int cmp(const void* a, const void* b)
{return (*(int*)a - *(int*)b);
}int main()
{int arr[] = {5, 2, 9, 1, 5, 6};int n = sizeof(arr) / sizeof(arr[0]);printf("Before sorting:\n");for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}printf("\n");qsort(arr, n, sizeof(int), cmp);printf("After sorting:\n");for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}printf("\n");return 0;
}
输出结果:
Before sorting: 5 2 9 1 5 6 After sorting: 1 2 5 5 6 9
2. 示例:对结构体数组排序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>struct stu
{int num;char name[10];int age;
};int cmp(const void* a, const void* b)
{struct stu* pa = (struct stu*)a;struct stu* pb = (struct stu*)b;if (pa->age != pb->age) {return pa->age - pb->age;} else {return strcmp(pa->name, pb->name);}
}void print_students(struct stu* students, int size)
{for (int i = 0; i < size; i++) {printf("Student %d: Num = %d, Name = %s, Age = %d\n", i + 1, students[i].num, students[i].name, students[i].age);}
}int main()
{struct stu students[3] = {{9801, "zhang", 20},{9802, "wang", 19},{9803, "zhao", 18}};printf("Before sorting:\n");print_students(students, 3);qsort(students, 3, sizeof(struct stu), cmp);printf("After sorting:\n");print_students(students, 3);return 0;
}
输出结果:
Before sorting: Student 1: Num = 9801, Name = zhang, Age = 20 Student 2: Num = 9802, Name = wang, Age = 19 Student 3: Num = 9803, Name = zhao, Age = 18 After sorting: Student 1: Num = 9803, Name = zhao, Age = 18 Student 2: Num = 9802, Name = wang, Age = 19 Student 3: Num = 9801, Name = zhang, Age = 20
二、知识点分析
1. qsort函数的参数
base参数
base
参数是指向要排序的数组的首地址。在C语言中,数组名本身就是一个指向数组首元素的指针,因此可以直接将数组名传递给 base
参数。
nitems参数
nitems
参数表示数组中元素的个数。可以通过 sizeof(arr) / sizeof(arr[0])
来计算数组中元素的个数。
size参数
size
参数表示数组中每个元素的大小(以字节为单位)。对于基本数据类型(如 int
、float
等),可以直接使用 sizeof
运算符来获取其大小。对于结构体类型,也可以使用 sizeof
运算符来获取其大小。
compar参数
compar
参数是一个比较函数的指针,用于定义排序的规则。比较函数的原型如下:
int cmp(const void* a, const void* b);
- 如果第一个参数小于第二个参数,返回负数。
- 如果第一个参数等于第二个参数,返回零。
- 如果第一个参数大于第二个参数,返回正数。
2. 比较函数的编写
比较函数是 qsort
函数的核心部分,它决定了排序的规则。比较函数的编写需要根据具体的需求来实现。以下是一些常见的比较函数的编写方法:
对整数数组排序
int cmp(const void* a, const void* b)
{return (*(int*)a - *(int*)b);
}
对浮点数数组排序
int cmp(const void* a, const void* b)
{if (*(float*)a < *(float*)b) {return -1;} else if (*(float*)a > *(float*)b) {return 1;} else {return 0;}
}
对字符串数组排序
int cmp(const void* a, const void* b)
{return strcmp(*(char**)a, *(char**)b);
}
对结构体数组排序
int cmp(const void* a, const void* b)
{struct stu* pa = (struct stu*)a;struct stu* pb = (struct stu*)b;if (pa->age != pb->age) {return pa->age - pb->age;} else {return strcmp(pa->name, pb->name);}
}
3. qsort函数的工作原理
qsort
函数是一种快速排序算法的实现。快速排序的基本思想是:选择一个基准值(pivot),将数组分为两部分,左边的部分都小于基准值,右边的部分都大于基准值,然后递归地对左右两部分进行排序。
qsort
函数的工作原理如下:
- 选择一个基准值(pivot)。
- 将数组分为两部分,左边的部分都小于基准值,右边的部分都大于基准值。
- 递归地对左右两部分进行排序。
三、注意事项
1. 比较函数的返回值
比较函数的返回值必须符合以下规则:
- 如果第一个参数小于第二个参数,返回负数。
- 如果第一个参数等于第二个参数,返回零。
- 如果第一个参数大于第二个参数,返回正数。
如果返回值不符合上述规则,可能会导致排序结果不正确。
2. 比较函数的参数类型
比较函数的参数类型是 const void*
,表示指向任意类型的指针。在比较函数中,需要将 const void*
类型的参数强制转换为具体的类型指针,然后进行比较。
3. 数组的大小
在调用 qsort
函数时,需要正确计算数组的大小。对于基本数据类型(如 int
、float
等),可以直接使用 sizeof
运算符来获取其大小。对于结构体类型,也可以使用 sizeof
运算符来获取其大小。
4. 数组的元素个数
在调用 qsort
函数时,需要正确计算数组的元素个数。可以通过 sizeof(arr) / sizeof(arr[0])
来计算数组中元素的个数。
四、拓展应用
1. 对结构体数组进行多级排序
在实际应用中,我们可能需要对结构体数组进行多级排序。例如,先按年龄排序,如果年龄相同,则按姓名排序。以下是一个示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>struct stu
{int num;char name[10];int age;
};int cmp(const void* a, const void* b)
{struct stu* pa = (struct stu*)a;struct stu* pb = (struct stu*)b;if (pa->age != pb->age) {return pa->age - pb->age;} else {return strcmp(pa->name, pb->name);}
}void print_students(struct stu* students, int size)
{for (int i = 0; i < size; i++) {printf("Student %d: Num = %d, Name = %s, Age = %d\n", i + 1, students[i].num, students[i].name, students[i].age);}
}int main()
{struct stu students[3] = {{9801, "zhang", 20},{9802, "wang", 19},{9803, "zhao", 18}};printf("Before sorting:\n");print_students(students, 3);qsort(students, 3, sizeof(struct stu), cmp);printf("After sorting:\n");print_students(students, 3);return 0;
}
2. 对结构体数组进行逆序排序
在实际应用中,我们可能需要对结构体数组进行逆序排序。以下是一个示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>struct stu
{int num;char name[10];int age;
};int cmp(const void* a, const void* b)
{struct stu* pa = (struct stu*)a;struct stu* pb = (struct stu*)b;if (pa->age != pb->age) {return pb->age - pa->age;} else {return strcmp(pb->name, pa->name);}
}void print_students(struct stu* students, int size)
{for (int i = 0; i < size; i++) {printf("Student %d: Num = %d, Name = %s, Age = %d\n", i + 1, students[i].num, students[i].name, students[i].age);}
}int main()
{struct stu students[3] = {{9801, "zhang", 20},{9802, "wang", 19},{9803, "zhao", 18}};printf("Before sorting:\n");print_students(students, 3);qsort(students, 3, sizeof(struct stu), cmp);printf("After sorting:\n");print_students(students, 3);return 0;
}
3. 对结构体数组进行部分排序
在实际应用中,我们可能需要对结构体数组进行部分排序。以下是一个示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>struct stu
{int num;char name[10];int age;
};int cmp(const void* a, const void* b)
{struct stu* pa = (struct stu*)a;struct stu* pb = (struct stu*)b;if (pa->age != pb->age) {return pa->age - pb->age;} else {return strcmp(pa->name, pb->name);}
}void print_students(struct stu* students, int size)
{for (int i = 0; i < size; i++) {printf("Student %d: Num = %d, Name = %s, Age = %d\n", i + 1, students[i].num, students[i].name, students[i].age);}
}int main()
{struct stu students[5] = {{9801, "zhang", 20},{9802, "wang", 19},{9803, "zhao", 18},{9804, "li", 21},{9805, "sun", 22}};printf("Before sorting:\n");print_students(students, 5);qsort(students + 1, 3, sizeof(struct stu), cmp);printf("After sorting:\n");print_students(students, 5);return 0;
}
4. 对结构体数组进行自定义排序
在实际应用中,我们可能需要对结构体数组进行自定义排序。以下是一个示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>struct stu
{int num;char name[10];int age;
};int cmp(const void* a, const void* b)
{struct stu* pa = (struct stu*)a;struct stu* pb = (struct stu*)b;if (pa->age != pb->age) {return pa->age - pb->age;} else {return strcmp(pa->name, pb->name);}
}void print_students(struct stu* students, int size)
{for (int i = 0; i < size; i++) {printf("Student %d: Num = %d, Name = %s, Age = %d\n", i + 1, students[i].num, students[i].name, students[i].age);}
}int main()
{struct stu students[3] = {{9801, "zhang", 20},{9802, "wang", 19},{9803, "zhao", 18}};printf("Before sorting:\n");print_students(students, 3);qsort(students, 3, sizeof(struct stu), cmp);printf("After sorting:\n");print_students(students, 3);return 0;
}
五、总结
qsort
函数是C语言中一个非常重要的概念,它允许我们将多个不同类型的数据组合在一起,形成一个逻辑上的整体。
关注窝,每三天至少更新一篇优质c语言题目详解~
[专栏链接QwQ] :⌈c语言日寄⌋CSDN
[关注博主ava]:siy2333
感谢观看~ 我们下次再见!!