C语言之——快速排序qsort库函数的讲解

2023-11-18

        qsort函数C语言编译器函数库自带的排序函数,也叫快速排序函数。之前我写过一篇关于冒泡排序的代码讲解,大家感兴趣的话可以先看一看我对于冒泡排序的讲解。

        相比较于冒泡排序,快速排序可以用更加快捷的速度去排列升降序,它的时间复杂度只有O(N*logN),冒泡排序的代码只能排列整型的数据,时间复杂度为O(n^2),比前者更高。(这么说吧,若是小明要从北京到上海,有两种方法,一种是坐火车(冒泡排序)去,一种是坐飞机(快速排序)去,由此可见其效率的不同。

        而快速排序函数qsort函数可以排列任何类型的数据,例如浮点型,字符型,结构体中可以按年龄大小排列,可以按名字首字母排列........

      1.  qsort 的函数声明是:

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

        

2.参数共4个

  • base-- 指向要排序的数组的第一个元素的指针。

  • nitems-- 由 base 指向的数组中元素的个数。

  • size-- 数组中每个元素的大小,以字节为单位。

  • compare-- 用来比较两个元素的大小的一个函数,是函数指针(回调函数)

回调函数:

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

        对于第四个参数,函数指针指向的compare函数,其参数有两个,分别是两个元素的地址p1与p2:

设p1接收&arr[0],                 p2接收&arr[1]:

若*(void*)p1 > *(void*)p2,则返回大于0的值;

若*(void*)p1 = *(void*)p2,则返回等于0的值;

若*(void*)p1 < *(void*)p2,则返回小于0的值;

        在函数指针中,void*表示空类型的指针(泛型指针),可以接收来自任何类型的元素地址,这就是快速排序函数可以排列多类型的核心要素。 

3.函数实践

        接下来让我们欣赏一下快速排序的实验案例吧!

//qsort函数——快速排序

# include<stdio.h>
#include<stdlib.h>

int cmp_t(const void* p1, const void* p2) {
	return(*(int*)p1 - *(int*)p2);
	}
int main() {
	int arr[] = { 1,7,6,4,5,9,3,2,0,8 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]),  cmp_t);
	int i = 0;
	for (i = 0; i < sz; i++) {
		printf("%d ", arr[i]);
	}
	return 0;
}

        注:  在函数cmp_t中,p1-p2完成的是升列排序,p2-p1完成降列排序。 你可以根据想要的顺序进行两指针位置的调换。

                 qsort传递的是指针,对于指针的比较,我们必须要将指针强制转化为相应的数据类型,比如排列浮点型数据,就将两指针强转为 (float*);排列字符型数据,就将两指针强转为( char*);排列结构体型数据就强转为( struct  结构体名称*)......


四.qsort函数对于其他类型的排序 

1.qsort对于结构体数组的排序

#include<stdlib.h>
#include<string.h>
struct Stu {
	char name[15];
	int age;
};

int cmp_t1(const void* p1, const void* p2) {//对姓名的排序
	return strcmp(((struct Stu*)p1)->name, ((struct Stu*)p2)->name);
}

void test1() {
	struct Stu s[3] = { {"zhangsan",23},{"lisi",19},{"wangwu",30} };
	int sz = sizeof(s) / sizeof(s[0]);
	//qsort(s, sz, sizeof(struct Stu), cmp_t1);——对姓名的排序

//打印数组
int i = 0;
	for (i = 0; i < sz; i++) {
		printf("%s ", s[i].name);
		printf("%d \n", s[i].age);
	}
}

int main() {
	test1();
	return 0;
}

        在上面的结构体成员变量中有姓名和年龄,我们可以选择姓名的首字母来进行对结构体数组的排序。姓名是字符串数据,那么我们便要使用字符串函数strcmp函数进行比较,还完美解决了回调函数返回值的问题

        strcmp函数实现方法是对两组字符串中相应位置的比较,例如"abcdef"和" abcrgitho" 这两个字符串,从两字符串的首字符一对一对的比较,串1的a与串2的a比较,比较大小相同,再向后进行比较,直到在两字符串的第四位置,串1是d,串2是r,字符r的ASCII码值大于字符c,所以字符串2大,*e1- *e2,所以字符串2会排序到靠后的位置。

#include<stdlib.h>

struct Stu {
	char name[15];
	int age;
};

int cmp_t2(const void* p1, const void* p2) {//对年龄的排序
	return ((struct Stu*)p1)->age- ((struct Stu*)p2)->age;
}

void test1() {
	struct Stu s[3] = { {"zhangsan",23},{"lisi",19},{"wangwu",30} };
	int sz = sizeof(s) / sizeof(s[0]);
	qsort(s, sz, sizeof(struct Stu), cmp_t2);//——对年龄的排序
	int i = 0;
	for (i = 0; i < sz; i++) {
		printf("%s ", s[i].name);
		printf("%d \n", s[i].age);
	}
}
int main() {
	test1();
	return 0;
}

2.qsort对浮点型数组的排序 

//qsort对浮点型数据的排序

int cmp_t(const void* p1, const void* p2) {
	return ((int)(*(float*)p1 - *(float*)p2));//float型指针相减的结果为float,需要强制转换为Int
}
int main() {
	float arr[] = { 9.0,8.0,7.0,6.0,5.0,4.0,3.0,2.0,1.0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]), cmp_t);


	int i = 0;
	for (i = 0; i < sz; i++) {
		printf("%2f ", arr[i]);
	}
	return 0;

 


         好了,对qsort函数的讲解就到这里,再次总结一下:qsort可以实现对任意类型数据的排序,功能强大,且需要掌握对四个参数的用法,尤其是第四个——函数指针,回调函数的使用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言之——快速排序qsort库函数的讲解 的相关文章

  • 工业异常检测AnomalyGPT-Demo试跑

    写在前面 如果你有大的cpu和gpu可以使用 直接根据官方的安装说明就可以 如果没有 可以点进来试着看一下我个人的安装经验 一 试跑环境 NVIDIA4090显卡24g cpu内存33G 交换空间8g 操作系统ubuntu22 04 试跑过
  • 华为OD机试真题-计算三叉搜索树的高度-2023年OD统一考试(C卷)

    题目描述 定义构造三叉搜索树规则如下 每个节点都存有一个数 当插入一个新的数时 从根节点向下寻找 直到找到一个合适的空节点插入 查找的规则是 1 如果数小于节点的数减去500 则将数插入节点的左子树 2 如果数大于节点的数加上500 则将数
  • 【质量-弹簧-阻尼系统】基于脉冲响应约束的子空间辨识研究(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码 数据 文章
  • J2EE常见面试题(一)

    StringBuilder和StringBuffer的区别 String 字符串常量 不可变 使用字符串拼接时是不同的2个空间 StringBuffer 字符串变量 可变 线程安全 字符串拼接直接在字符串后追加 StringBuilder
  • 排序:计数排序

    一 概念 计数排序是非比较排序 是对哈希直接定址法的变形应用 二 思想 利用数组统计相同数据出现的次数 例如整型数据m出现n次 就在数组m位置记录数据为n 最后从头遍历数组打印数据即可 通俗来讲就是 数组下标即为数据 下标所指位置的值即为数
  • 蒙特卡洛在发电系统中的应用(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码实现
  • 带头双向循环链表基础

    带头双向循环链表基础 销毁 销毁 void ListDestory ListNode phead void ListDestory ListNode phead assert phead ListNode cur phead gt next
  • 华为OD机试真题-API集群负载统计-Java-OD统一考试(C卷)

    题目描述 某个产品的RESTful API集合部署在服务器集群的多个节点上 近期对客户端访问日志进行了采集 需要统计各个API的访问频次 根据热点信息在服务器节点之间做负载均衡 现在需要实现热点信息统计查询功能 RESTful API的由多
  • 链表的中间节点

    链表的中间节点 力扣 LeetCode 官网 全球极客挚爱的技术成长平台 备战技术面试 力扣提供海量技术面试资源 帮助你高效提升编程技能 轻松拿下世界 IT 名企 Dream Offer https leetcode cn problems
  • 矩阵基本操作3

    题目描述 问题描述 定义一个N M N M lt 100 的矩阵 将一个该矩阵的行和列的元素互换 存到另一个二维数组中 输入格式 一行两个整数 N M 中间用空格隔开 表示矩阵有N行 M列 接下来共N行M列表示矩阵 输出格式 输出转置以后的
  • 矩阵基本操作2

    题目描述 问题描述 将方阵 n 行n列 n lt 100 置成下三角矩阵 主对角线右上角数字全部清零 输入格式 第一行输入n 接下来的n行每行n列 表示矩阵的数值 用空格隔开 输出格式 n行n列下三角矩阵 每个数字3个占位符 左对齐 输入样
  • 数据结构——排序

    前言 哈喽小伙伴们好久不见 也是顺利的考完试迎来了寒假 众所周知 不怕同学是学霸 就怕学霸放寒假 假期身为弯道超车的最佳时间 我们定然是不能懒散的度过 今天我们就一起来学习数据结构初阶的终章 七大排序 本文所有的排序演示都为升序排序 目录
  • ​LeetCode解法汇总82. 删除排序链表中的重复元素 II

    目录链接 力扣编程题 解法汇总 分享 记录 CSDN博客 GitHub同步刷题项目 https github com September26 java algorithms 原题链接 力扣 LeetCode 描述 给定一个已排序的链表的头
  • 做大模型也有1年多了,聊聊这段时间的感悟!

    自ChatGPT问世以来 做大模型也有1年多了 今天给大家分享这一年后的感悟 过去一年应该是AI圈最万千瞩目的一年了 大家对大模型 OpenAI ChatGPT AI Native Agent这些词投入了太多的关注 以至于有一年的时间好像经
  • 【牛客周赛Round 27】题目讲解

    题目一 小红的二进制删数字 小红拿到了一个二进制字符串 s 她可以删掉其中的一些字符 使得最终该字符串为一个2的幂 即可以表示为 2 k 形式的数 小红想知道 自己最少删几个字符可以达成 请你编写一个函数返回这个答案 具体思路 看到这道题目
  • 【自适应滤波】一种接近最佳的自适应滤波器,用于突发系统变化研究(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码及文章
  • 基于卡尔曼的混合预编码技术用于多用户毫米波大规模MIMO系统研究(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码及文章
  • 『力扣刷题本』:逆波兰表达式求值

    大家好久不昂 最近 1 个多月罗根一直在备考期末 文章发的很少 现在已经放寒假啦 学习自然也不能拉下 毕竟 4 月份就要去参加蓝桥杯了 先给自己定个小目标 日更 2 篇 咳咳 下面马上开始讲题 一 题目 给你一个字符串数组 tokens 表
  • 2024年华为OD机试真题-虚拟游戏理财-Python-OD统一考试(C卷)

    题目描述 在一款虚拟游戏中生活 你必须进行投资以增强在虚拟游戏中的资产以免被淘汰出局 现有一家Bank 它提供有若干理财产品m 风险及投资回报不同 你有N 元 进行投资 能接受的总风险值为X 你要在可接受范围内选择最优的投资方式获得最大回报
  • 最大流-Dinic算法,原理详解,四大优化,详细代码

    文章目录 零 前言 一 概念回顾 可略过 1 1流网络 1 2流 1 3最大流 1 4残留网络 1 5增广路

随机推荐