快速排序qsort讲解

        hello大家好,我是c语言boom家宝,今天为大家分享的博客内容是qsort快速排序,简称快排的一个知识点的讲解。

        在讲到快排之前,允许博主先提一嘴冒泡排序。大家在c语言的学习过程中,冒泡排序是必不可少会学习到的一个思想,那么冒泡排序是怎么样的呢?我们看代码:

int main() {int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };int i = 0;int sz = sizeof(arr) / sizeof(int);for (i = 0; i < sz - 1; i++) {  //一共要交换多少次数int j = 0;for (j = 0; j < sz - 1 - i; j++) {  //每一次交换的元素个数if (arr[j] > arr[j + 1]) {int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}for (i = 0; i < sz; i++) {printf("%d ", arr[i]);}return 0;
}

        这样就完成一个冒泡排序啦,非常的简单。但是冒泡排序简单是简单,可是效率十分的低。它通过重复很多次的挨个比较,然后交换的方式达成最后的排序效果。如果数组内容非常非常的多呢?那么排序所用的时间将会非常的多。其次,上面的这个冒泡排序只适用于排序整型。如果我又需要对其他类型的数据排序,如浮点型,字符型等,那么就需要重新写一个冒泡排序的代码,十分的复杂。基于这几点原因,所以博主将讲解一下qsort快速排序的使用:

 

        库函数qsort,快排,适用于任何类型数据的排序。使用时需要引用<stdlib.h>头文件
博主在官网上查询qsort的使用方法,它们是这样介绍的:如图

        我们再来看一下使用qsort库函数需要调用的参数是什么

        那么qsort函数的返回值是什么,如图:

         也就是说如果p1指向的元素值小于p2指向的元素值,返回一个小于0的数。反之,返回一个大于0的数。如果相等,则返回0.

        总结一下,当我们要使用qsort库函数的时候,需要传的参数如下。他们各自表示的意思也有打在备注里面,方便大家理解。如果不知道什么是函数指针,请移步链接:http://t.csdn.cn/FtRCn,博主有在里面对函数指针进行讲解,这很重要,因为要想使用qsort库函数,必须要创建一个函数指针才可以。

void qsort(void* base,   //指向了需要排序的数组的第一个元素size_t num,   //排序的元素个数size_t size,  //一个元素的大小,单位是字节int (*cmp)(const void*,const void*)  //函数指针类型,//这个函数指针指向的函数,需要能够比较base指向数组中的两个元素);

        细心的阅读朋友会发现,这个函数指针的参数部分类型是const void*类型。而void*这个类型有一些特殊,void*不能直接进行解引用操作,也不能直接进行指针的运算。但是,void*指针是无具体类型的指针,它可以接收任意类型的地址。这一点就十分妙哉,因为我们在使用函数过程中并不会提前知道你具体会传过来什么类型的参数。如果还像上面冒泡排序一样,那么就写死了,就只能完成一个类型数据的排序。 既然不能直接解引用,那我们就可以在使用的时候把它强制转换成我们需要的类型。具体实现如下:

#include <stdio.h>
#include <stdlib.h>int cmp_int(const void* p1, const void* p2) {return(*(int*)p1 - *(int*)p2);
}void test1() {int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };int sz = sizeof(arr) / sizeof(int);//qsort默认排的是升序qsort(arr, sz, sizeof(arr[0]), cmp_int);int i = 0;for (i = 0; i < 10; i++) {printf("%d ", arr[i]);}
}
int main() {test1();return 0;
}

        qsort默认是排成升序,如果想排成降序,我们只需要把上述代码中的return(*(int*)p1 - *(int*)p2);改成return(*(int*)p2 - *(int*)p1);就可以了。上述代码编译结果如下

        当然,前面也说到过,qsort可以排序任何一个类型的。博主这里再举例用qsort来排序结构体又是怎么排序的呢?代码如图

        我们只需要按照格式去传参数,然后写一个函数指针就可以了。qsort有着十分高效的效率,各位阅读朋友可以自己尝试一下去写一个快排出来 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/11744.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

有关合泰BA45F5260中断的思考

最近看前辈写的代码&#xff0c;发现这样一段代码&#xff1a; #ifdef SUPPORT_RF_NET_FUNCTION if(UART_INT_is_L()) { TmrInsertTimer(eTmrHdlUartRxDelay,TMR_PERIOD(2000),NULL); break; } #endif 其中UART_INT_is_L&am…

C++对C的加强(全)

目录 C对C的加强 命名空间 为什么要使用命名空间 怎么使用命名空间 命名空间的定义 命名空间的使用 使用域解析符 :: 使用using声明 内联命名空间 嵌套命名空间 随时将新的成员加入命名空间 命名空间中 函数的声明和实现分开 无名命名空间 命名空间取别名 使用u…

【通讯录】--C语言

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

路由策略(重发布)

要求&#xff1a; 1、使用双点双向重发布 2、所有路由器进行最佳选路 3、存在备份路径&#xff0c;不得出现环路&#xff0c;和路由回馈 1.更改设备名称配置接口IP地址 R1 <Huawei>system-view [Huawei]sysname R1 [R1]interface GigabitEthernet 0/0/0 [R1-GigabitEt…

Python深度学习“四大名著”之一【赠书活动|第二期《Python机器学习:基于PyTorch和Scikit-Learn》】

近年来&#xff0c;机器学习方法凭借其理解海量数据和自主决策的能力&#xff0c;已在医疗保健、 机器人、生物学、物理学、大众消费和互联网服务等行业得到了广泛的应用。自从AlexNet模型在2012年ImageNet大赛被提出以来&#xff0c;机器学习和深度学习迅猛发展&#xff0c;取…

MATLAB与ROS联合仿真(慕羽☆)全套开源资料索引

自2021年9月份开始进行MATLAB与ROS联合仿真相关的研究&#xff0c;至2021年12月份研究基本上结束&#xff0c;至今&#xff0c;已经近两年时间&#xff0c;期间曾收到过很多小伙伴的私信&#xff0c;想让我出点教程&#xff0c;期间我也曾多次想要抽点时间出教程&#xff0c;但…

JMeter 怎么查看 TPS 数据教程,简单易懂

TPS 是软件测试结果的测量单位。一个事务是指一个客户机向服务器发送请求然后服务器做出反应的过程。客户机在发送请求时开始计时&#xff0c;收到服务器响应后结束计时&#xff0c;以此来计算使用的时间和完成的事务个数。在 JMeter 中&#xff0c;我们可以使用以下方法查看 T…

华为战略方法论:BLM模型之关键任务与依赖关系

内容简介 在 BLM 模型中&#xff0c;执行部分包括四个模块&#xff0c;分别是&#xff1a; 关键任务与依赖关系&#xff1b;组织与绩效&#xff1b;人才&#xff1b;氛围与文化。 详细内容&#xff0c;大家可以参看下面这张图。 这四个模块其实是可以进一步划分成两个关键点…

MFC自定义控件使用

用VS2005新建一个MFC项目,添加一个Custom Control控件在窗体 我们需要为自定义控件添加一个类。项目,添加类,MFC类 设置类名字,基类为CWnd,你也可以选择CDialog作为基类 类创建完成后,在它的构造函数中注册一个新的自定义窗体,取名为"MyWindowClass" WNDCL…

8.11 PowerBI系列之DAX函数专题-TopN中实现N的动态

需求 实现 1 ranking by amount rankx(allselected(order_2[产品名称]),[total amount]) 2 rowshowing_boolean var v_ranking [ranking by amount] var v_topN-no [topN参数 值] var v_result int( v_ranking < v_topN_no) return v_result 3 将度量值2放入视觉对象筛…

大数据Flink(五十二):Flink中的批和流以及性能比较

文章目录 Flink中的批和流以及性能比较 ​​​​​​​​​​​​​​一、Flink中的批和流

【网络云盘客户端】——上传文件的功能的实现

目录 上传文件功能的实现 uploadtask的设计 设置上传的槽函数 uploadFileAction接口 uploadFile接口 定时上传文件 进度条的设计 上传文件功能的实现 上传文件功能实现 1.双击 ”上传文件 “的 QListWidgetItem 或者 点击 “上传” 菜单项 都会弹出一个文件对话框 2.在文…

华为云安装MySQL后,本地工具连接MySQL失败

华为云安装MySQL后&#xff0c;本地连接失败 排查问题步骤&#xff1a; 在此之前需要在MySQL创建用户&#xff0c;并赋予权限。 1、能否ping通。 在本地命令行(Windows&#xff1a;winR)通过ping命令&#xff0c;ping服务器地址&#xff0c;看能否ping通。不能则需要检查本地…

【C++入门】浅谈类、对象和 this 指针

文章目录 一、前言二、类1. 基本概念2. 类的封装3. 使用习惯成员函数定义习惯成员变量命名习惯 三、对象1. 基本概念2. 类对象的存储规则 四、this 指针1. 基本概念2. 注意事项3. 经典习题4. 常见面试题 一、前言 在 C 语言中&#xff0c;我们用结构体来描述一个事物的多种属性…

ubuntu docker离线安装docker(.deb包方式)(成功)(附卸载方法)

参考文章&#xff1a;Install Docker Engine on Ubuntu 文章目录 安装步骤下载安装包拷贝到目标主机并执行安装命令 验证拉取运行容器测试build dockerfile测试持久运行容器测试主机重启后&#xff0c;docker各服务是否正常自启 卸载方法附&#xff1a;各安装包作用说明&#x…

express编写一个简单的get接口

/01编写get接口.jsconst express require(express) const app express()// 创建路由 const useRouter require(./router/user.js) // 注册路由 app.use(/api,useRouter)app.listen(8080, (req, res) > {console.log(8080监听) }) ./02编写post接口 // 注意&#xff1a;如…

mac cli文件管理器

背景 最近研究了一下在控制台查看文件的插件ranger, 官方的解释是&#xff1a;一个cli下的文件管理器。觉得效果也很酷炫&#xff0c;所以在此展示一下。 安装 brew install ranger配置生成 建议第一次使用的时候使用 ranger --copy-configall将会在~/.config/ranger目录输…

Solr原理剖析

一、简介 Solr是一个高性能、基于Lucene的全文检索服务器。Solr对Lucene进行了扩展&#xff0c;提供了比Lucene更为丰富的查询语言&#xff0c;并实现了强大的全文检索功能、高亮显示、动态集群&#xff0c;具有高度的可扩展性。同时从Solr 4.0版本开始&#xff0c;支持SolrCl…

STM32 CAN通讯实验程序

目录 STM32 CAN通讯实验 CAN硬件原理图 CAN外设原理图 TJA1050T硬件描述 实验线路图 回环实验 CAN头文件配置 CAN_GPIO_Config初始化 CAN初始化结构体 CAN筛选器结构体 接收中断优先级配置 接收中断函数 main文件 实验现象 补充 STM32 CAN通讯实验 CAN硬件原理图…

【RabbitMQ】之高可用集群搭建

目录 一、RabbitMQ 集群原理 1、默认集群原理2、镜像集群原理3、负载均衡方案 二、RabbitMQ 高可用集群搭建 1、RabbitMQ 集群搭建2、配置镜像队列3、HAProxy 环境搭建4、Keepalived 环境搭建 一、RabbitMQ 集群简介 1、默认集群原理 3-1、RabbitMQ 集群简介 单台 RabbitM…