【C语言】详细介绍qsort和模拟实现qsort

news/2024/12/13 4:46:56/

在这里插入图片描述

🚀write in front🚀
📝个人主页:认真写博客的夏目浅石.
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝
📣系列专栏:凡人修C传
💬总结:希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🖊
✉️如果无聊的话,就来逛逛我的博客栈吧stack-frame.cn

文章目录

  • 前言
  • 一、qsort函数介绍
  • 二、qsort的作用
  • 三、qsort的参数
  • 四、qsort的用法
    • 4.1排序整形数组
    • 4.2排序其他类型
  • 五、模拟实现qsort函数
    • 5.1主函数书写
    • 5.2泡泡排序的书写
    • 5.3比较函数和交换函数的实现
    • 5.4整形数组排序的总代码
    • 5.5所有类型数组的排序代码总结
  • 总结


前言

今天给大家介绍C语言中一个比较好用的函数qsort函数以及我们模拟实现qsort函数的过程。


提示:以下是本篇文章正文内容,下面案例可供参考

一、qsort函数介绍

示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
这里是qsort函数的介绍,在下面简单的给大家翻译介绍一下

二、qsort的作用

首先最上面说到它的作用,执行一个快速排序,qsort函数是一个排序函数,它的底层排序算法是快速排序

想要了解快速排序的可以去这里学习,链接已经附上,快去学习吧~

【algorithm】算法基础课—排序算法(附笔记 | 建议收藏)

三、qsort的参数

void qsort( void *base, size_t num, size_t width, int (__cdecl *compare )(const void *elem1, const void *elem2 ) );`

接着就是它的返回值和参数,我们可以看到这长长的一串,看着就头疼,不过也没大家想象的那么复杂,给大家介绍一下大家就明白了。

首先看我们的第一个参数base,就是一个我们待排序的数组,接着就是num,顾名思义就是我们数组元素的的大小,待排序元素的个数,然后就是width参数,也就是我们待排元素中每个元素的大小,最后就是int (__cdecl *compare )(const void *elem1, const void *elem2 )这是一个回调函数,其中compare是一个函数指针,函数的两个参数分别是elem1elem2(类型是void*)返回值是int类型,最后qsort的返回类型是void型。

四、qsort的用法

4.1排序整形数组

#include<stdio.h>
#include<stdlib.h>
//整数的比较
int cmp1(const void* e1, const void* e2)
{return *((int*)e1) - *((int*)e2);
}
//测试整数
void test1()
{int arr[5] = { 5,4,3,2,1 };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), cmp1);for (int i = 0; i < 5; i++){printf("%d ", arr[i]);}printf("\n");}
int main()
{test1();return 0;
}

在这里插入图片描述

4.2排序其他类型

//浮点数的比较
int cmp2(const void* e1, const void* e2)
{return *((double*)e1) - *((double*)e2);
}
//字符的比较
int cmp3(const void* e1, const void* e2)
{return *((char*)e1) - *((char*)e2);
}
//字符串的比较
int cmp4(const void* e1, const void* e2)
{return strcmp(*(char**)e1, *(char**)e2);
}
//结构体数字比较
int cmp5(const void* e1, const void* e2)
{return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
//结构体字符串比较
int cmp6(const void* e1, const void* e2)
{return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}

五、模拟实现qsort函数

由于目前考虑让更多人理解qsort函数的使用,所以博主就打算带着大家,利用泡泡排序的思路来详细讲解qsort

5.1主函数书写

int main()
{int arr[]={9,8,7,6,5,4,3,2,1,0};int sz=sizeof(arr)/sizeof(arr[0]);//四个参数对标qsort的四个参数bubble_sort(arr,sz,sizeof(arr[0]),cmp_int);for(int i=0;i<sz;i++){printf("%d ",arr[i]);}return 0;
}

5.2泡泡排序的书写

void bubble_sort(void* base,int sz,int width,int (cmp_int)(const void* e1,const void* e2))
{int i=0;for(i=0;i<sz-1;++i){int j=0;for(j=0;j<sz-i-1;++j){if(cmp_int((char*)base+j*width,(char*)base+(j+1)*width)>0){Swap((char*)base+j*width,(char*)base+(j+1)*width,width);}}}
}

在这里插入图片描述

5.3比较函数和交换函数的实现

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 tmp=*buf1;*buf1=*buf2;*buf2=tmp;buf1++;buf2++;}
}

在这里插入图片描述

5.4整形数组排序的总代码

#include<stdio.h>
#include<stdlib.h>
#include<string.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 tmp=*buf1;*buf1=*buf2;*buf2=tmp;buf1++;buf2++;}
}void bubble_sort(void* base,int sz,int width,int (cmp_int)(const void* e1,const void* e2))
{int i=0;for(i=0;i<sz-1;++i){int j=0;for(j=0;j<sz-i-1;++j){if(cmp_int((char*)base+j*width,(char*)base+(j+1)*width)>0){Swap((char*)base+j*width,(char*)base+(j+1)*width,width);}}}
}int main()
{int arr[]={9,8,7,6,5,4,3,2,1,0};int sz=sizeof(arr)/sizeof(arr[0]);bubble_sort(arr,sz,sizeof(arr[0]),cmp_int);for(int i=0;i<sz;i++){printf("%d ",arr[i]);}return 0;
}

5.5所有类型数组的排序代码总结

在这里插入图片描述

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct Stu
{int age;char name[20];
};
//整数的比较
int cmp1(const void* e1, const void* e2)
{return *((int*)e1)-*((int*)e2);
}
//浮点数的比较
int cmp2(const void* e1, const void* e2)
{return *((double*)e1) - *((double*)e2);
}
//字符的比较
int cmp3(const void* e1, const void* e2)
{return *((char*)e1) - *((char*)e2);
}
//字符串的比较
int cmp4(const void* e1, const void* e2)
{return strcmp(*(char**)e1, *(char**)e2);
}
//结构体数字比较
int cmp5(const void* e1, const void* e2)
{return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
//结构体字符串比较
int cmp6(const void* e1, const void* e2)
{return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}//模拟实现qsort函数
void swap(char* ch1, char* ch2, int sz)
{for (int i = 0; i < sz; i++){char tem = *ch1;*ch1 = *ch2;*ch2 = tem;ch1++;ch2++;}
}
void bubble_sort(void* arr, int num, int size, int (*cmp)(const void* e1, const void* e2))
{for (int i = 0; i < num; i++){for (int j = 0; j < num - i - 1; j++){//cmp((char*)arr + j * size, (char*)arr + (j + 1) * size)if (cmp((char*)arr + j * size, (char*)arr + (j + 1) * size)){swap((char*)arr + j * size, (char*)arr + (j + 1) * size, size);}}}
}
//测试整数
void test1()
{int arr[5] = { 5,4,3,2,1 };int sz = sizeof(arr) / sizeof(arr[0]);bubble_sort(arr, sz, sizeof(arr[0]), cmp1);for (int i = 0; i < 5; i++){printf("%d ", arr[i]);}printf("\n");}//测试浮点数
void test2()
{double arr[5] = { 2.5,2.3,3.8,6.1,0.2 };int sz = sizeof(arr) / sizeof(arr[0]);bubble_sort(arr, sz, sizeof(arr[0]), cmp2);for (int i = 0; i < 5; i++){printf("%.1lf ", arr[i]);}printf("\n");
}
//测试字符
void test3()
{char arr[5] = { 'e','f','o','a','q' };int sz = sizeof(arr) / sizeof(arr[0]);bubble_sort(arr, sz, sizeof(arr[0]), cmp3);for (int i = 0; i < 5; i++){printf("%c ", arr[i]);}printf("\n");
}
//测试字符串
void test4()
{char* arr[] = { "shan","huani","ajfie","deygufefb" };int sz = sizeof(arr) / sizeof(arr[0]);bubble_sort(arr, sz, sizeof(arr[0]), cmp4);for (int i = 0; i < sz; i++){printf("%s ", arr[i]);}printf("\n");
}
//测试结构体中的排序
void test5()
{struct Stu arr[4] = { {11,"uheriu"},{37,"iuehen"},{8,"aouenioon"},{22,"ming"} };int sz = sizeof(arr) / sizeof(arr[0]);bubble_sort(arr, sz, sizeof(arr[0]), cmp5);for (int i = 0; i < sz; i++){printf("%d ", arr[i].age);}printf("\n");bubble_sort(arr, sz, sizeof(arr[0]), cmp6);for (int i = 0; i < sz; i++){printf("%s ", arr[i].name);}
}
int main()
{test1();test2();test3();test4();test5();return 0;
}

总结

我是夏目浅石,希望和你一起学习进步,刷题无数!!!希望各位大佬能一键三连支持一下博主,hhhh~我们下期见喽

在这里插入图片描述
如果无聊的话,就来逛逛我的博客栈吧stack-frame.cn

原创不易,还希望各位大佬支持一下\textcolor{blue}{原创不易,还希望各位大佬支持一下}原创不易,还希望各位大佬支持一下

👍 点赞,你的认可是我创作的动力!\textcolor{9c81c1}{点赞,你的认可是我创作的动力!}点赞,你的认可是我创作的动力!

⭐️ 收藏,你的青睐是我努力的方向!\textcolor{ed7976}{收藏,你的青睐是我努力的方向!}收藏,你的青睐是我努力的方向!

✏️ 评论,你的意见是我进步的财富!\textcolor{98c091}{评论,你的意见是我进步的财富!}评论,你的意见是我进步的财富!


http://www.ppmy.cn/news/22703.html

相关文章

【TypeScript】TS 看这一篇就够了

文章目录&#x1f9d1;‍&#x1f4bb;TypeScript基本概念TypeScript 是什么&#xff1f;为什么要有typescript安装编译 TS 的工具包编译并运行 TS 代码创建基于TS的vue项目&#x1f9d1;‍&#x1f4bb;TypeScript基础类型注解TypeScript类型概述TypeScript原始数据类型数组类…

SSM整合配置

SSM整合配置1. module结构2. pom.xml3. resources3.1 jdbc.properties&#xff1a;4. config4.1 SpringConfig&#xff1a;4.2 JdbcConfig&#xff1a;4.3 MybatisConfig&#xff1a;4.4 SpringMvcConfig&#xff1a;4.5 ServletInitializer&#xff1a;★1. module结构 SSM整…

【数据结构基础】图 - 最小生成树(Prim Kruskal)

Kruskal算法是从最小权重边着手&#xff0c;将森林里的树逐渐合并&#xff1b;prim算法是从顶点出发&#xff0c;在根结点的基础上建起一棵树。最小生成树相关名词连通图: 在无向图中&#xff0c;若任意两个顶点vivi与vjvj都有路径相通&#xff0c;则称该无向图为连通图。强连通…

【Web开发】Python实现Web服务器(CentOS下运行Flask)

文章目录1、简介2、安装2.1 安装Centos2.2 安装python2.3 安装虚拟环境2.4 修改国内源2.5 安装flask库3、测试3.1 flask官方例子结语1、简介 CentOS 大家应该很熟悉了&#xff0c;英文全称&#xff1a;Community Enterprise Operating System&#xff08;社区企业操作系统&…

Spring Cloud Gateway源码

文章目录一、背景1. 核心概念2. 工作流程3.动态路由二、自动配置源码解析1.GatewayAutoConfiguration2.WebFluxAutoConfiguration3.HttpHandlerAutoConfiguration三、请求过程源码解析1. 整体流程2. NettyWebServer接收http请求3.请求和响应转换4.HttpWebHandlerAdapter5. Exce…

怎么使用【Davinci Cfg】配置CanNM Bus load reduction功能

文章目录 1 涉及的模块2 配置的参数传送门 ==>> AutoSAR入门和实战系列总目录 1 涉及的模块 配置CanNM Bus load reduction功能要用到NM和CanNM模块,NM是抽象出来的,它独立于使用的具体总线,CanNM是CAN总线的NM. 2 配置的参数 要配置使用某个通道的Bus load reduc…

C++之生产者和消费者模型分析(条件变量)

先看一下生产者消费者模型概述&#xff1a;生产者把需要处理的数据放到缓存队列中并向消费者发出信号&#xff0c;然后消费者把数据拿出来处理&#xff0c;这里生产者可以是单线程或者多线程&#xff0c;而消费者一般是多线程&#xff0c;消费者线程集合也称线程池。下面再举一…

【Java 数据结构】模拟实现 HashMap

目录 1、前言 2、成员变量的设定 3、构造方法 4、hash 方法以及 阈值判断方法 5、put 方法 5、resize 方法 6、get 方法 1、前言 上期讲解了 HashMap 和 HashSet 的一些相关源码&#xff0c;本期我们就来简单的模拟实现一下 HashMap&#xff0c;当然肯定没有源码那么的…