qsort函数使用举例

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 *));

         其中,各个参数的含义如下:

  1. base:指向待排序数组的指针,即将要排序的数组的首地址。
  2. nmemb:待排序数组中元素的个数。
  3. size:排序数组的一个元素(即数组中的一个元素)的大小(以byte为单位)。
  4. 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语言相关的知识和技巧,也欢迎继续关注我们的文章。感谢大家的阅读!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值