• 【C语言】qsort函数



    前言

    qsort函数是八大排序算法中的快速排序,能够排序任意数据类型的数组,包括实现整型,浮点型,结构体,字符串等的排序。

    一、qsort函数原型

    头文件:#include<stdio.h>

    void qsort(void* base,//要排序的数据的首元素地址
    	       int num,//要排序的数据个数
    	       int width,//元素的字节大小
    	       void(*cmp)(const void* e1, const void* e2));//函数指针-接收比较函数,比较函数需要我们自己实现
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    关于为什么要使用void*指针:首先要明确void**是无具体类型的指针,可以接受任意类型的地址,而qsort函数可以排序多种类型的数据,所以我们利用空指针接受地址。需要注意的是空指针没有确定的步长大小,所以空指针不能加减整数,不能对空指针进行解引用。

    二、

    1.qsort函数实现整型排序

    (1)升序

    #include<stdio.h>
    #include<stdlib.h>
    //整型的比较函数
    int cmp_int(const void* e1, const void* e2)
    {
    	return *(int*)e1 - *(int*)e2;
    }
    int main()
    {
    	int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
    	int sz = sizeof(arr) / sizeof(arr[0]);
    	//qsort库函数的使用
    	qsort(arr, sz, sizeof(arr[0]), cmp_int);
    	int i = 0;
    	for (i = 0; i < sz; i++)
    	{
    		printf("%d ", arr[i]);
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    (2)降序

    #include<stdio.h>
    #include<stdlib.h>
    int cmp_int(const void* e1, const void* e2)
    {
    	return *(int*)e2 - *(int*)e1;//后一个元素比前一个元素大,就交换
    }
    int main()
    {
    	int arr[] = { 0,1,2,3,4,5,6,7,8,9,10 };
    	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]);
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    2.qsort函数实现结构体排序

    (1)按年龄排序

    #include<stdio.h>
    #include<stdlib.h>
    //定义结构体类型
    struct Stu
    {
        //结构体成员
    	int age;
    	char name[20];
    };
    int cmp_stu_by_age(const void* e1, const void* e2)
    {   
        //需要e1需要括号括起,才能访问到结构体数据
    	return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
    }
    int main()
    {
    	struct Stu s[] = { {30,"lisi"},{20,"wangwu"},{10,"zhangsan"} };
    	int sz = sizeof(s) / sizeof(s[0]);
    	qsort(s, sz, sizeof(s[0]), cmp_stu_by_age);
    	int i = 0;
    	for (i = 0; i < sz; i++)
    	{
    		printf("%d %s\n", s[i].age, s[i].name);
    	}
    	return 0;
    }
    
    • 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

    (2)按名字排序

    #include<stdio.h>
    #include<stdlib.h>
    struct Stu
    {
    	int age;
    	char name[20];
    };
    int cmp_stu_by_name(const void* e1, const void* e2)
    {
        //字符串的比较用strcmp
    	return strcmp(  ((struct Stu*)e1)->name, ((struct Stu*)e2)->name  );
    }
    int main()
    {
    	struct Stu s[] = { {30,"lisi"},{20,"wangwu"},{10,"zhangsan"} };
    	int sz = sizeof(s) / sizeof(s[0]);
    	qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);
    	int i = 0;
    	for (i = 0; i < sz; i++)
    	{
    		printf("%d %s\n", s[i].age, s[i].name);
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    三. 冒泡排序算法模拟实现qsort函数

    (1)排序整数

    #include<stdio.h>
    //比较函数
    int cmp_int(const void* e1, const void* e2)
    {
    	return *(int*)e1 - *(int*)e2;
    }
    //以字节单位交换
    void Swap(char* buf1, char* buf2, int width)//以字节为单位交换
    {
    	int i = 0;
    	for (i = 0; i < width; i++)
    	{
    		char temp = *buf1;
    		*buf1 = *buf2;
    		*buf2 = temp;
    		buf1++;
    		buf2++;
    	}
    }
    void bubble_sort(char* base, int sz, int width, int(*cmp)(int, int))
    {
    	int i = 0;
    	int j = 0;
    	int flag = 0;
    	for (i = 0; i < sz - 1; i++)
    	{
    		flag = 1;
    		for (j = 0; j < sz - 1 - i; j++)
    		{
    		    //强制类型转换成char*类型
    			if (cmp_int((char*)base+j*width,(char*)base+(j+1)*width)>0)
    			{
    				Swap((char*)base + j * width, (char*)base + (j + 1)*width, width);
    				flag = 0;
    			}
    		}
    		if (flag == 1)
    		{
    			break;
    		}
    	}
    }
    int main()
    {
    	int arr[] = { 1,3,5,7,9,2,4,6,8,0 };
    	int sz = sizeof(arr) / sizeof(arr[0]);
    	bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);
    	int i = 0;
    	for (i = 0; i < sz; i++)
    	{
    		printf("%d ", arr[i]);
    	}
    	return 0;
    }
    
    • 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

    (2)排序浮点数

    #include<stdio.h>
    float cmp_float(const void* e1, const void* e2)
    {
    	return *(float*)e1 - *(float*)e2;
    }
    void Swap(char* buf1, char* buf2, int width)//以字节为单位交换
    {
    	int i = 0;
    	for (i = 0; i < width; i++)
    	{
    		char temp = *buf1;
    		*buf1 = *buf2;
    		*buf2 = temp;
    		buf1++;
    		buf2++;
    	}
    }
    void bubble_sort(void* base, int sz, int width, int(*cmp)(void*, void*))
    {
    	int i = 0;
    	int j = 0;
    	int flag = 0;
    	for (i = 0; i < sz - 1; i++)
    	{
    		flag = 1;
    		for (j = 0; j < sz - 1 - i; j++)
    		{
    			if (cmp_float((char*)base+j*width,(char*)base+(j+1)*width)>0)
    			{
    				Swap((char*)base + j * width, (char*)base + (j + 1)*width, width);
    				flag = 0;
    			}
    		}
    		if (flag == 1)
    		{
    			break;
    		}
    	}
    }
    int main()
    {
    	float arr[] = { 9.0,8.0,7.0,6.0,5.0,4.0,3.0,1.1,1.0 };
    	int sz = sizeof(arr) / sizeof(arr[0]);
    	int i = 0;
    	bubble_sort(arr, sz, sizeof(arr[0]), cmp_float);
    	for (i = 0; i < sz; i++)
    	{
    		printf("%.1f ", arr[i]);
    	}
    	return 0;
    }
    
    • 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
  • 相关阅读:
    【Mysql系列】(一)MySQL语句执行流程
    从零开始的C++(十一)
    比较分析线程池中execute与submit方法的差异
    [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(白虎组)
    2Gcsv文件打不开怎么处理,使用byzer工具
    虹科分享 | 测试与验证复杂的FPGA设计(2)——如何在IP核中执行面向全局的仿真
    302. 包含全部黑色像素的最小矩形 BFS
    VScode + opencv + c++ + win配置教程
    一种基于堆的链式优先队列实现(使用golang)
    网络编程,UDP通信程序,TCP通信程序
  • 原文地址:https://blog.csdn.net/weixin_63449996/article/details/125621081