服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C语言 使用qsort函数来进行快速排序

C语言 使用qsort函数来进行快速排序

2022-09-16 14:08诚挚的乔治 C/C++

排序方法有很多种:选择排序,冒泡排序,归并排序,快速排序等。 看名字都知道快速排序是目前公认的一种比较好的排序算法。因为他速度很快,所以系统也在库里实现这个算法,便于我们的使用。 这就是qsort函数

前言

今天分享一个库函数

介绍qsort的使用及实现方法

他可以实现不限于整形、浮点型、字符型、自定义等类型的排序

qsort的简单介绍

  qsort
头文件 #include <stdlib.h>
格式 void qsort(void* base,size_t num,size_t width,int(__cdecl*compare(const void*,const void*))
功能 实现多类型的快速排序
返回值 无返回值

把格式分解 

?
1
2
3
4
5
void qsort(void* base,
           size_t num,
           size_t width,
           int(* compare)(const void* e1, const void* e2)
           );

qsort的首参数为待排列数组的首地址

size_t num为某个类型的个数

size_t width为类型的宽度,也就是该类型的大小

int(* compare)(const void* e1, const void* e2)为比较函数的指针,这里是利用函数指针作为参数,实现传参

这里运用了回调函数的思想

回调函数就是通过函数指针调用的函数,如果把一个函数的指针(地址)当作参数,传给另一个函数,当这个函数调用所指的函数时,我们就说这是回调函数。

用qsort实现一个整形类型的排序

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include<stdio.h>
#include<stdlib.h>
int cmp_int(const void* e1, const void* e2)
{
    return (*(int*)e1) - (*(int*)e2);
}
 
void test1()
{
    int arr[] = { 1,4,2,6,5,3,7,9,0,8 };
    int sz = sizeof(arr) / sizeof(arr[0]);
    qsort(arr, sz, sizeof(arr[0]), cmp_int);
    int i = 0;
    for (i = 0; i < sz; i++)
    {
        printf("%d ", arr[i]);
    }
    printf("\n");
}
 
int main()
{
    test1();
    return 0;
}

C语言 使用qsort函数来进行快速排序

用qsort函数实现结构体的排序

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include<stdio.h>
#include<stdlib.h>
struct Stu
{
    char name[20];
    int age;
    float score;
};
 
int cmp_stu_by_socre(const void* e1, const void* e2)  //结构体中的浮点型
{
    if (((struct Stu*)e1)->score > ((struct Stu*)e2)->score)
    {
        return 1;
    }
    else if (((struct Stu*)e1)->score < ((struct Stu*)e2)->score)
    {
        return -1;
    }
    else
    {
        return 0;
    }
}
 
int cmp_stu_by_age(const void* e1, const void* e2)     //结构体中的整形
{
    return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
 
int cmp_stu_by_name(const void* e1, const void* e2)    //结构体中的字符型
{
    return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}
 
void print_stu(struct Stu arr[], int sz)  //打印函数
{
    int i = 0;
    for (i = 0; i < sz; i++)
    {
        printf("%s %d %f\n", arr[i].name, arr[i].age, arr[i].score);
    }
    printf("\n");
}
void test4()
{
    struct Stu arr[] = { {"zhangsan",20,87.5f},{"lisi",22,99.0f},{"wangwu", 10, 68.5f} };
    //按照成绩来排序
    int sz = sizeof(arr) / sizeof(arr[0]);
    qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_socre);
    print_stu(arr, sz);
    qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_age);
    print_stu(arr, sz);
    qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_name);
    print_stu(arr, sz);
}
 
int main()
{
    test4();
    return 0;
}

结构体的成员包括整形,浮点型和字符型

分别从小到大来排列 

cmp函数通过返回值的正负性来实现比较大小,就可以实现下图的结果

C语言 使用qsort函数来进行快速排序

qsort函数的实现

qsort函数在实现的时候,其实跟冒泡排序有一定的联系

只不过

相对于冒泡排序,它可以排序各类型的数据,下面通过对比来实现其函数的功能

冒泡排序实现整形的排序

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void bubble(int arr[],int sz)  //冒泡排序实现整形的排序
{
    int tmp = 0; int i = 0; int j = 0;
    for (i = 0; i < sz - 1; i++)
    {
        for (j=0;j<sz-1;j++)
        {
            if (arr[j] > arr[j + 1])
            {
                tmp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = tmp;
            }
        }
    }
}

qsort函数的实现

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
void Swap(char* buf1, char* buf2, int width)
{
    int i = 0;
    for (i = 0; i < width; i++)
    {
        char tmp = *buf1;
        *buf1 = *buf2;
        *buf2 = tmp;
        buf1++;
        buf2++;
    }
}
 
void bubble_sort(void* base, int sz, int width, int(*cmp)(const void* e1, const void* e2))
{
    int i = 0;
    for (i = 0; i < sz - 1; i++)
    {
        int j = 0;
        for (j = 0; j < sz - 1 - i; j++)
        {
            //if (arr[j] > arr[j + 1])
            if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
            {
                //两个元素的交换
                Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
            }
        }
    }
}

可以看出有两个地方有差异

首先就是两个元素比较大小,是通过cmp比较函数实现

当返回值大于零,函数就实现从小到大来排序

当返回值小于零,函数就实现从大到小来排序

当返回值等于零,元素不发生变化

第二个差异就是,实现两个元素的交换

冒泡排序就是通过引入一个中间变量,达到交换的目的

而qsort函数,通过调用一个函数,通过引入宽度(所占字节的大小),进行字节之间的交换,所以用char类型来实现不同类型的交换,所以首先需要知道排序数组内每一个元素的大小,整形就交换四个字节的空间即可。

到此这篇关于C语言 使用qsort函数来进行快速排序的文章就介绍到这了,更多相关C语言 qsort函数内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://z-ming.blog.csdn.net/article/details/122774748

延伸 · 阅读

精彩推荐
  • C/C++Objective-C的内省(Introspection)用法小结

    Objective-C的内省(Introspection)用法小结

    这篇文章主要介绍了Objective-C的内省(Introspection)用法,这是面向对象语言和环境的一个强大特性,需要的朋友可以参考下...

    C语言程序设计7292021-01-21
  • C/C++详解C语言之单链表

    详解C语言之单链表

    这篇文章主要为大家介绍了C语言的单链表,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助...

    ぃ咔哇依°ヽ11702022-02-25
  • C/C++基于c++ ege图形库实现五子棋游戏

    基于c++ ege图形库实现五子棋游戏

    这篇文章主要为大家详细介绍了基于c++ ege图形库实现五子棋游戏,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    libingbojava10392021-07-15
  • C/C++深入理解C语言指针及占据内存空间

    深入理解C语言指针及占据内存空间

    这篇文章主要介绍了C语言指针及占据内存空间的相关知识,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下...

    拿着保温瓶的年轻人8652021-08-16
  • C/C++C语言金币阵列问题解决方法

    C语言金币阵列问题解决方法

    这篇文章主要介绍了C语言金币阵列问题解决方法,主要涉及数组的灵活运算,是一类非常经典的算法,需要的朋友可以参考下...

    C语言程序设计13002021-02-02
  • C/C++C语言 浅谈栈与队列的定义与操作

    C语言 浅谈栈与队列的定义与操作

    栈和队列,严格意义上来说,也属于线性表,因为它们也都用于存储逻辑关系为 "一对一" 的数据,但由于它们比较特殊,因此将其单独作为一章,做重点讲...

    王不患吖吖吖5592022-02-20
  • C/C++c++ 写注册表方式让程序开机自启动

    c++ 写注册表方式让程序开机自启动

    这篇文章主要介绍了c++ 写注册表方式让程序开机自启动,需要的朋友可以参考下...

    kwsy20083962021-06-02
  • C/C++C++哈希应用的位图和布隆过滤器

    C++哈希应用的位图和布隆过滤器

    这篇文章主要介绍了C++哈希应用的位图和布隆过滤器的相关资料,文章内容多以列举试题的方式讲解,感兴趣的朋友可以参考下面文章内容...

    森明帮大于黑虎帮7952021-12-30