qsort函数作用
qsort()函数是C语言标准库中的一个排序函数,可以对任意类型的数组进行排序。该函数接收四个参数,分别是待排序数组的起始地址、元素数量、每个元素的大小和一个自定义的比较函数指针。其中比较函数指针指向一个比较两个元素大小的函数,函数返回值为负数表示第一个元素小于第二个元素,返回值为零表示两个元素相等,返回值为正数表示第一个元素大于第二个元素。
使用qsort()函数需要满足以下几点要求:
1. 待排序的数组中的元素应该是可比较的,即它们的大小关系可以通过比较函数确定;
2. 比较函数必须是可重入的,即不能使用任何静态变量或全局变量;
3. 比较函数不能改变待排序数组中元素的值。
qsort()函数采用快速排序算法进行排序,时间复杂度为O(n log n),是一种高效的排序算法,可以用于大部分排序需求。 在使用qsort()函数时,需要注意元素类型和比较函数的实现,特别是比较函数的返回值要满足上述规定,否则可能会导致排序结果不正确。
qsort函数中参数的含义
我们首先看一下qsort函数中的参数都有哪些。qsort函数是C标准库中的一个排序函数,其函数原型如下:
void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
其中,各个参数的含义如下:
base
:指向待排序数组的指针,即将要排序的数组的首地址。nmemb
:待排序数组中元素的个数。size
:排序数组的一个元素(即数组中的一个元素)的大小(以byte为单位)。compar
:函数指针,指向一个用来比较两个元素的函数。该函数必须返回一个整数值,如果第一个元素比第二个元素小,则返回负数,否则返回正数,如果两个元素相等,则返回零。该函数的原型为:int (*compar)(const void *, const void *)
。
在调用qsort函数时,我们需要传入比较函数指针,该函数用于指定两个元素之间的排序规则,而待排序的数组以及数组中元素的大小则用于帮助qsort库函数进行排序操作。排序函数的结果将会直接影响到原始数组,因此在调用qsort函数之前,我们需要确保待排序的数组中每个元素都是合法的,且合适的数据类型已经被使用。
qsort的使用方法
qsort排序整型类型数组
使用qsort函数进行排序,我们先以整形为例,需要完成以下几个步骤:
- 定义待排序的数组以及数组元素的数据类型。
int array[] = {5, 2, 8, 7, 1, 9, 3, 6, 4};
int n = sizeof(array) / sizeof(array[0]);
- 定义比较函数,该函数指定两个元素之间的大小关系。
int compare(const void *p, const void *q)
{
int x = *(const int *)p;
int y = *(const int *)q;
if (x < y)
return -1;
else if (x > y)
return 1;
else
return 0;
}
- 比较函数返回值的意义:
如果第一个参数小于第二个参数,返回-1。
如果第一个参数大于第二个参数,返回1。
如果第一个参数等于第二个参数,返回0。
- 调用qsort函数进行排序。
qsort(array, n, sizeof(int), compare);
array
:待排序的数组。
n
:数组元素的个数。
sizeof(int)
:每个元素的大小,以byte为单位。
compare
:比较函数的函数指针。
- 排序完成后,数组的元素顺序已经被改变,可以直接打印输出数组元素观察排序结果。
输出结果为:for (int i = 0; i < n; i++) { printf("%d ", array[i]); }
1 2 3 4 5 6 7 8 9
以下是利用qsort函数排序整型类型的完整代码
完整代码
#include <stdio.h>
#include <stdlib.h>
int compare(const void *p, const void *q)
{
int x = *(const int *)p;
int y = *(const int *)q;
if (x < y)
return -1;
else if (x > y)
return 1;
else
return 0;
}
int main()
{
int array[] = {5, 2, 8, 7, 1, 9, 3, 6, 4};
int n = sizeof(array) / sizeof(array[0]);
qsort(array, n, sizeof(int), compare);
for (int i = 0; i < n; i++)
{
printf("%d ", array[i]);
}
printf("\n");
return 0;
}
需要注意的是,使用qsort函数进行排序时,我们需要自己编写比较函数指定排序规则。比较函数的编写需要根据实际需求进行,如果只是想简单地对整型数组进行升序排序,则可以直接使用上述示例代码中的比较函数。但对于其他类型的数组,比如字符串或者结构体类型的数组,需要自己编写相应的比较函数。
qsort排序字符串类型数组
有了排序整型类型数组的经验,我们就可以尝试排序字符串类型数组了。
假设我们有一个字符串类型的数组arr[]
,数组大小为n
,我们打算对其进行排序。
- 定义字符串类型数组和数组大小。
char *arr[] = {"john", "peter", "bob", "alice", "anna"};
int n = sizeof(arr) / sizeof(arr[0]);
在这个例子中,我们定义了一个字符串类型的数组arr[]
,并将一些姓名赋值给它。我们还通过sizeof
运算符计算了数组大小,并将结果存储在整型变量n
中。
- 定义比较函数。
int compare(const void *a, const void *b)
{
return strcmp(*(const char **)a, *(const char **)b);
}
在这个函数中,我们使用了strcmp()
函数来比较两个字符串的大小,并返回相应的值。为了将void
类型的指针转换为char
类型的指针,我们使用了一个强制类型转换,将void
类型的指针强制转换为char
类型的指针。因为我们正在处理的是字符串类型的数组,所以我们需要使用双重指针来访问它们。
- 调用qsort函数进行排序。
qsort(arr, n, sizeof(char *), compare);
在这里,我们使用qsort()
函数对字符串类型数组进行排序。它的第一个参数是我们要排序的数组,第二个参数是数组大小,第三个参数是每个元素的大小(在这种情况下,是指针的大小),最后一个参数是比较函数。
- 输出排序结果。
printf("Sorted array: \n");
for (int i = 0; i < n; i++)
{
printf("%s\n", arr[i]);
}
- 最后,我们使用循环遍历已排序的数组,以便输出排好序的结果。接下来是详细代码:
完整代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int compare(const void *a, const void *b)
{
return strcmp(*(const char **)a, *(const char **)b);
}
int main()
{
char *arr[] = {"john", "peter", "bob", "alice", "anna"};
int n = sizeof(arr) / sizeof(arr[0]);
qsort(arr, n, sizeof(char *), compare);
printf("Sorted array: \n");
for (int i = 0; i < n; i++)
{
printf("%s\n", arr[i]);
}
return 0;
}
qsort排序结构体类型数组
使用qsort()
函数排序结构体类型数组的步骤如下:
- 定义结构体类型并为其定义比较函数。
int compare_structs(const void* a, const void* b)
其中,a和b分别表示待比较的两个结构体指针。
比较函数需要返回一个整数表示a和b的大小关系。若a小于b,返回负数;若a等于b,返回0;若a大于b,返回正数。
-
定义结构体类型数组并初始化。
-
使用
qsort()
函数进行排序。
排序函数的形式为:
void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*))
- 在排序函数中调用比较函数进行比较。
以下是一个使用 qsort()
函数排序结构体类型数组的示例代码:
完整代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
int id;
char name[20];
float score;
} Student;
int compare_students(const void* a, const void* b)
{
const Student* ptr_a = (const Student*)a;
const Student* ptr_b = (const Student*)b;
if(ptr_a->score < ptr_b->score) return 1;
else if(ptr_a->score > ptr_b->score) return -1;
else return 0;
}
int main()
{
Student students[] =
{
{1, "Tom", 80},
{2, "Jerry", 75},
{3, "Alice", 90},
{4, "Bob", 85},
{5, "John", 92}
};
int num_students = 5;
printf("Before sorting:\n");
for (int i = 0; i < num_students; i++)
{
printf("%d %s %.2f\n", students[i].id, students[i].name, students[i].score);
}
qsort(students, num_students, sizeof(Student), compare_students);
printf("\nAfter sorting:\n");
for (int i = 0; i < num_students; i++)
{
printf("%d %s %.2f\n", students[i].id, students[i].name, students[i].score);
}
return 0;
}
输出结果:
Before sorting:
1 Tom 80.00
2 Jerry 75.00
3 Alice 90.00
4 Bob 85.00
5 John 92.00
After sorting:
5 John 92.00
3 Alice 90.00
4 Bob 85.00
1 Tom 80.00
2 Jerry 75.00
写在最后的话
通过这篇文章,我们了解了qsort函数在C语言中的应用以及其实现原理。通过对快速排序算法的研究,我们可以更好地理解qsort函数的实现过程并在实际编程中利用这个函数来进行快速排序。同时,了解如何编写自定义比较函数也是非常重要的,可以让我们更加灵活地使用qsort函数,并提高程序的效率和可读性。总之,qsort函数是一个非常有用的工具,学会如何使用它将会使我们在C语言编程中更加得心应手。希望这些内容能够帮助您更好地理解和应用qsort函数。如果您需要进一步了解其他C语言相关的知识和技巧,也欢迎继续关注我们的文章。感谢大家的阅读!