万能排序qsort(快排)or万能冒泡

C语言qsort函数详解:从原理到实战的通用排序指南 排序是数据处理与算法设计中的基础操作,其核心目标是将数据集合按照特定规则重新排列。从经典的冒泡排序、快速排序等算法原理出发,排序的价值在于提升数据检索效率、优化存储结构,广泛应用于数据库索引、游戏排行榜、数据分析等场景。C标准库中的qsort函数通过通用指针和回调函数机制,实现了对任意数据类型的快速排序。本文以qsort函数为焦点,深入解析其函数原型、快速排序算法原理,并通过整型数组、结构体数组及指针数组等实战案例,演示如何编写安全的比较函数、规避整数溢出等常见陷阱。掌握qsort不仅能提升C语言编程效率, 阅读详情

目录

前言:

Qsort函数

"万能"冒泡排序

总结

前言:

在c语言中排序的方式有很多种,哪有没有一种排序可以应对绝大部分情况的排序呢,在c语言中的内置函数qsort就是一种"万能排序",那么借用他的逻辑还可以衍生出万能"冒泡排序".

Qsort函数:  头文件为 <stdlib.h>

void qsort(void *base, int nelem, unsigned int width, int (* pfCompare)(const void *,const void *))

qsort函数的底层逻辑是快排,所以时间复杂度与快排相同。上面为qsort的使用方式,我会为大家用小"栗子"来讲述如何使用和操作.

 void qsort :显然qsort函数的返回值是void 

 void *base:是将要进行排序数组

 int nelem :将排序的数组长度传过去

 unsigned int width :待排序的数组每个元素的大小

 int (* pfCompare)(const void *,const void *): 往简单的说就是使用者自己提供的比较函数

#include<stdlib.h>
int main()
{
	int arr[] = { 2,6,1,4,7,9,12,8,3 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]), cap_int);
	return 0;
}

​

 这里讲一下 sz ,sizeof(arr)是整个数组的大小,那么sizeof(arr[0])就是数组元素中第一个元素的大小,那么 sz 其实就代表了 数组 的宽度.

那么这个时候cap_int怎么写呢(这个需要用户自己提供):如下

int cap_int(const void* e1, const void* e2)
{
	return *(int*)e1 - *(int*)e2;
}

①-->为什么cap_int 接收时候需要const void *而不能使用其他的来接收呢?

这是因为我们void好像一个垃圾桶,他什么类型的数据他都接收保存,这样就大大的增强了代码的通用性质.

②-->在return 时将void*强制转化成int*

③-->cap_int 形参接收的到底是什么的值呢?

形参中接收的是数组arr中带比较的两个数,譬如e1是arr[0]的地址,e2是arr[1]的地址,而强制转化的作用就是让接受到的两个数据可以相减.

④-->这么设置是qsort的升序,而降序只需要更改成 return *(int*)e1-*(int*)e2 ;

上面讲述的是使用qsort给整形数组排序,那么接下来我们来给结构体排排;

struct stu
{
	char name[20];
	int year; 
};
int cam_stu_by_year(const void* e1, const void* e2)
{
	return ((struct stu*)e1)->year - ((struct stu*)e2)->year;
}
void text1()
{
	struct stu arr[3] = { { "张三",8 },{"李四",6},{"王五",1} };
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]), cam_stu_by_year);
}

这里的sizeof就有奇效了!

道理就和上面的一模一样!

利用这种思想我们来试试万能冒泡!

"万能"冒泡排序

底层逻辑还是冒泡排序,所以时间复杂度还是O(n^2),但是它稳定(doge)

先来写一个冒泡:

int main()
{
	int i,j;
	int arr[] = { 9,7,5,4,2,1 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (i = 0; i < sz - 1; i++)
	{
		for (j = 0; j < sz - i - 1; j++)
		{
			if (arr[j] > arr[j+1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
	return 0;
}

冒泡的外层for循环决定趟数,内存for循环来比较数组中两个数的值,但这种冒泡排序并不能比较非整形数据.

那么我们就要创造一个万能的冒泡排序,也是因此bubble_sort的形参就很有考究了

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

void text4()
{
	int arr[] = { 9,8,7,6,5,4,3,2,1 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	bubble_sort(arr, sz, sizeof(arr[0]), cap_int);
	int i;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}

}

还是老规矩,*base是待排序数组,num是整个数组大小,width是每个数据的大小(宽度)

*(cmp)就是函数指针了,他是由我们用户来自定义的也是用来判断传参数据的大小,他的作用和cap_int 一样,就是换了个名字使代码易读。

让我们理解一下这个代码 : cmp((char*)base + j * width, (char*)base + (j + 1) * width)

cmp就是函数cap_int,那么函数cap_int的作用就是比较两个参数的大小.

Q1:那么为什么要把参数都强制转化成char(*)?

char(*)在内存中占用一个字节是int*是四个字节

char*是精度最高的,如果你强制转化成int(*),在本题中是没有问题,但是如果比较7个字节为width的数据,那么int(*)的准确度显然不够高

Q2:(char*)base + j * width这段话怎么解释?

如果j=0 那么(char*)base + j * width就等于(char*)base,指向数组中第一个元素

如果j=1 那么(char*)base + j * width就指向了数组中第二个元素了

最后一步就是实现Swap函数了,先上代码:

void Swap(char* buf1, char* buf2,int width)
{
	int i;
	for (i = 0; i < width; i++)
	{
		char tmp = *buf1;
		*buf1 = *buf2;
		*buf2 = tmp;
		buf1++;
		buf2++;
	}
}

 这时候就突出强调了转化成char(*)的重要性了,如果是int(*)那么++将会跳过四个字节

swap函数在内存中是这么操作:

把arr[1](值为9)和arr[2](值为8)交换

09 00 00 00 和 08 00 00 00交换时就是将09和08交换,再继续将后面的数组交换

02 03 04 05 和 06 07 08 09交换就是将02和06、03和07、04和08、05和09交换

从而达到交换值的效果

总结

qsort和万能冒泡的思想都是一样的,多看看我相信一定能看懂,对于对指针有一定基础的人理解起来应该是更容易的,void*是一个垃圾桶他可以接受任意类型数据的指针,这也是能实现"万能"的原因

C语言qsort函数深度解析:从原理到实战避坑指南 在C语言编程中,排序是数据处理的基础操作,其核心在于高效地比较和交换元素。快速排序算法通过分治策略,平均时间复杂度可达O(n log n),是泛型排序实现的经典选择。C标准库中的qsort函数正是这一思想的体现,它通过void指针和回调函数机制,实现了对任意数据类型的排序,极大提升了代码的复用性和可移植性。理解qsort的关键在于掌握其比较函数的编写,这直接决定了排序的规则与正确性。在实际工程中,无论是嵌入式系统、操作系统内核开发,还是需要高可移植性的C项目,qsort都是不可或缺的工具。本文将深入剖析qs 阅读详情

相关推荐

AlphaDev用强化学习在汇编层优化排序算法

排序算法是计算机科学的基础概念,其本质是在确定性约束下实现元素的有序映射;传统分析聚焦于抽象时间复杂度,但真实性能取决于指令级执行效率、分支预测、缓存行为等硬件特性;强化学习自动编程为此提供了新范式——通过在精简指令集(如RISC-V)上建模状态-动作空间,并以周期数、指令数、内存访问为奖励信号,AI可直接生成经形式化验证的最优小规模排序原语;这类技术已落地LLVM与嵌入式场景,显著提升标准库原子操作性能;AlphaDev正是这一方向的代表性实践,它不替代高层逻辑开发,而是重构底层‘零开销抽象’的实现方式。

HJ921004的博客 297

C语言库函数——快排函数qsort()

qsort包含在头文件中,根据你给出的比较函数进行快速排序,通过指针移动实现排序,排序之后的结果仍然放在原数组中,使用qsort函数必须自己写一个比较函数。注意:qsort()函数无返回值。

weixin_73141021的博客 1827

手把手教你用思岚RPLIDAR C1激光雷达实现简单环境扫描(树莓派4B+Ubuntu22.04)

本文详细介绍了如何在树莓派4B(Ubuntu 22.04系统)上驱动思岚RPLIDAR C1激光雷达,从硬件连接、权限配置、SDK编译到运行示例程序,最终实现环境扫描数据的可视化。通过手把手教程,帮助开发者和爱好者快速上手激光雷达应用,构建简单的环境扫描图。

j2k3l4的博客 1133

快排函数 -- qsort函数(Quick Sort)

👁️qsort()函数是C语言库函数中的一种排序算法,其用到的排序思想是快速排序(quicksort)。它的独特之处在于可以排序任意类型的数组元素(整型、浮点型、字符串和结构体类型)可以参考一下 cplusplus 中的资料👇🔴使用qsort来排序整型数组,这里就由qsort函数的使用者来提供一个比较函数(自定义函数),这个比较函数能够比较2个整数的大小🔴。

weixin_74937672的博客 5818

anaconda安装-超详细版

文章目录一、anaconda安装1.1 anaconda安装地址1.2 安装详细步骤检验安装是否成功更改conda源(后续安装第三方库可以加快速度) 一、anaconda安装 Anaconda 是一个用于科学计算的 Python 发行版,支持 Linux, Mac, Windows, 包含了众多流行的科学计算、数据分析的 Python 包。装anaconda,就不需要单独装python了。 anaconda优点: 1、anaconda里面集成了很多关于python科学计算的第三方库,主要是安装方便,而p

in546的博客 25万+

汉字跨越三千年的生命力与数字时代适应性

文字作为文明载体,其演变规律始终遵循实用性与适应性的平衡。汉字作为现存最古老的文字系统,凭借形义结合的六书构造原理,实现了超方言的文化统一功能。在计算机处理方面,五笔输入法与Unicode支持证明了其技术兼容性,而视觉识别效率的先天优势使其在信息时代更具传播效力。从甲骨文识别AI到现代书法设计,汉字系统持续展现强大的文化承载力与技术适应性,这种活态传承为数字人文研究提供了独特样本。

weixin_29058331的博客 355

C语言——冒泡排序和qsort排序

这里需要注意的是,前面提到过,qsort可以对任意类型的数据进行排序,所以,qsort函数对于参数的类型的选择,使用void*进行表示,void*可以匹配任意类型的数据,但是,因为void*可以匹配任意类型的数据,所以在前面提到的不同类型指针的特殊性质,即指针和整数的加减以及指针的访问权限在void*指针上均不满足。所以,在书写比较函数的代码时,需要进一步将void*类型的数据,强制转换成被排序的数组的数据类型,例如,上面对int型的数据进行排序,则在书写比较函数时,需要将void*转为int*类型。

2301_76836325的博客 393

《低功耗方法学》翻译——卷首语

低功耗设计方法学。

记录所学,分享知识,结识挚友 992

qsort()函数(快速排序)

快排函数-----qsort()

Lucky.Mr.Li的博客 2471

电路设计仿真软件:Mentor Graphics_(11).MentorGraphics软件操作与技巧

/ 定义自定义仿真命令// 加载设计文件// 运行仿真// 主函数return 1;return 0;// 自定义设计检查// 获取设计中的所有模块// 遍历所有模块// 检查模块名称是否符合规范if (!// 检查模块中的所有引脚if (!// 主函数main() {通过本节的学习,您应该已经掌握了如何在 Mentor Graphics 中进行二次开发,包括使用 Tcl、C++ 和 Python 进行基本和高级操作。

kkchenjj的博客 1643

Ansible 面板工具之AWK ( Anssible Tower )界面介绍

整理这部分笔记博文内容为AWX和UI 界面的简单介绍理解不足小伙伴帮忙指正傍晚时分,你坐在屋檐下,看着天慢慢地黑下去,心里寂寞而凄凉,感到自己的生命被剥夺了。当时我是个年轻人,但我害怕这样生活下去,衰老下去。在我看来,这是比死亡更可怕的事。--------王小波这里AWX使用的是最新的版本AWX 21.7.0目前最新版是3.8.6,博客中的版本为3.5.0对于Redhat的,官网上看到在 2022 年 11 月之后不在维护了,改版之后现在叫,感兴趣小伙伴可以了解下虽然有AWX是。

山河已无恙 1303

排序 | 冒泡排序的优化与qsort快速排序

冒泡排序 冒泡排序 Bubble_Sort,是极为简单的一种排序算法。虽然效率差一点,但好在具有结构简单,容易理解,易于操作等优点。冒泡排序就是把小的元素往前调或者把大的元素往后调。在相邻的两个元素间比较,交换也发生在这两个元素之间。 冒泡排序是一种稳定排序算法,在排序后相同元素的前后顺序并没有改变。 相比于传统的冒泡排序,平均时间复杂度为O(n2),最好的时间复杂度为2,是一种效率不高的的排序。...

专注于C/C++/Linux领域创作 750

【Flink】Flink 消费一段时间1万多条数据就卡死

我们有个现场环境,发现了奇怪的现象,就是每次启动任务后,消费1万多条数据后就会卡死,然后整个流不消费,也不往下输出,看起来卡死了一样。缺图这里面出现的网闸原因导致的,但是经过我们写了一个简单的kafka消费程序,然后在出问题的节点上消费数据,实际排查,发现不是这个问题。这个问题,发现也不是,这段时间没有进行过kafka数据清理。里面的问题。因为这个问题,我们后面的代码刻意规范了,不这样操作。后来是在没办法了,然后我们dump了线程,发现有如下代码。

九师兄 351

排序算法还在手写?万能排序神器qsort函数,搞定90%笔试面试!

排序算法还在手写?万能排序神器qsort函数,搞定90%笔试面试!

萧邯嵌入式笔记 1161

解锁RK3588芯片超强网络性能:多队列网卡与IRQ负载均衡实战

摘要:本文针对RK3588芯片的网络性能优化展开研究,重点探讨了多队列网卡配置和IRQ负载均衡技术。通过配置多队列网卡,将网络流量分散到多个队列处理,显著提升了吞吐量(测试显示提升67%)。同时,通过IRQ负载均衡配置使中断请求均匀分配到各CPU核心,CPU利用率降低至35%。文章详细介绍了配置步骤、测试方法,并分析了常见问题及解决方案。这些优化措施有效提升了RK3588在网络录像机、边缘计算等应用场景中的性能表现,为高性能网络应用提供了有力支持。

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 499

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

用快排的思维模拟实现“万能“的冒泡排序--“Qsort“

1.先来看一看刚学习c语言时,那时我们写的冒泡排序 那时因为能力有限,把代码写死了,只能对整形的数组进行排序。 2.那么问题来了,以后想要对字符数组,浮点型数组,结构体数组进行排序的时候,我们应 该如何设计代码呢? 改进: 运用快速排序的思路(快排的函数:qsort) 参照优快云:qsort 解析: 参数1:void*类型的指针,可以接收任何类型的数组的地址; 参数2:接收数组的长度; 参数3:数组中一个元素的字节长度; 参数4:...

xaiobit_hl的博客 573

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

qsort函数

C语言中qsort函数

Jambo!的博客 1138

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

C语言qsort模拟实现:内存模型、迭代快排与嵌入式安全实践

qsort是C语言中理解泛型编程与内存操作的核心接口,其本质是基于void*指针的字节级内存搬运与分治排序。掌握其原理需深入理解指针算术(如char*强制转换)、size_t边界计算、栈式迭代替代递归等底层机制。在嵌入式开发中,qsort模拟实现直接关联栈空间控制、内存对齐安全、无malloc约束等关键工程能力;在算法学习中,它串联起partition划分、三数取中防退化、比较函数溢出防护等经典考点。本文以可落地的迭代快排实现为线索,覆盖从PTA练习题到CAN报文排序的真实场景,提供符合ASAM标准与MCU

weixin_30907935的博客 394

从qsort到通用排序引擎:C语言回调函数与泛型编程实践

在数据处理中,排序是基础且高频的操作,其核心目标是将数据元素按照特定规则高效组织。从经典的冒泡排序到快速排序,算法效率的差异源于不同的数据组织和比较策略。回调函数作为一种关键编程范式,允许将易变的比较逻辑从固定的排序框架中分离,这正是实现通用排序引擎的技术原理。通过函数指针,排序算法可以操作任意数据类型的内存块,而无需关心其具体结构,这种设计模式极大地提升了代码的复用性和灵活性,是泛型编程思想的典型体现。本文以C语言标准库qsort为蓝本,深入剖析了其利用void指针和比较函数实现通用排序的机制,并手把手指

weixin_34292402的博客 443

C语言qsort函数详解:从原理到实战,掌握万能排序技巧

在C语言程序开发中,排序是数据处理的基础操作,涉及算法效率、内存管理和数据类型处理等核心概念。快速排序算法因其平均时间复杂度优异而广泛应用,C标准库通过qsort函数将其封装为通用排序工具。该函数利用函数指针和void*类型实现泛型编程,将比较逻辑委托给用户自定义的回调函数,从而支持对整型、浮点型、字符串及复杂结构体等多种数据类型进行排序。其技术价值在于分离算法实现与数据比较逻辑,提供了高度优化且类型安全的排序方案。在数据结构操作、学生成绩管理、文件列表整理等应用场景中,qsort能显著提升开发效率与代码可

weixin_42116058的博客 282

【初识C语言】qsort 函数保姆级教程,搞定各种数据类型的排序

本文详细介绍了C语言标准库中的qsort函数,这是一个支持多种数据类型的通用快速排序工具。文章首先解析了qsort函数的4个核心参数:数组首地址、元素个数、元素大小和自定义比较函数。重点讲解了比较函数的编写规则,通过返回值决定排序顺序(负数表示正序,正数表示降序)。随后分类型展示了int、float/double、char以及字符串的排序实现方法,特别强调了浮点数比较时的精度问题处理技巧。最后还介绍了结构体数组的排序方式,帮助读者全面掌握qsort函数的使用技巧,实现高效便捷的数据排序。

2301_82161965的博客 1031

深入理解C语言qsort:从快速排序原理到手写泛型排序实现

排序算法是计算机科学的基础,快速排序因其平均O(n log n)的时间复杂度而广泛应用。其核心原理是分治策略,通过选取枢轴将数组划分为子序列递归排序。在C语言中,标准库的qsort函数通过泛型设计和回调函数机制,实现了对任意数据类型的排序,这体现了算法与数据分离的编程思想。理解其底层实现,尤其是函数指针和内存操作,对于掌握系统编程和性能优化至关重要。本文以快速排序和回调函数为切入点,通过手写my_qsort的实践,详细解析了分区算法、小数组优化等工程细节,并对比了标准库实现的性能与健壮性,帮助开发者深化对核

weixin_33226548的博客 214

排序类...

└── 分配排序类 (核心:利用“多关键字”分配和收集,不依赖比较) ←── 这里补上你问的“基数排序”│ └── 堆排序 (利用堆结构选最值) ←── 这里补上你问的“选择排序”├── 选择排序类 (核心:在待排序列中选出最值,放到最终位置)├── 交换排序类 (核心:通过比较并交换元素位置来排序)├── 插入排序类 (核心:将元素插入到已有序的序列中)│ └── 希尔排序 (本质:多次分组插入排序)│ ├── 简单选择排序 (直接选最值)│ ├── 直接插入排序。

qq_43519774的博客 299

【算法】常见基础算法

常见算法:双指针、滑动窗口、前缀和、二分、分治归并、分治快排、BFS、DFS、递归、回溯、FloodFill等

志之所趋,无远弗届,穷山距海,不能限也 1328

快速排序和qsort函数详解详解qsort函数

💕是非成败转头空,青山依旧在,几度夕阳红💕作者:Mylvzi文章主要内容:快速排序和qsort函数详解。

Mylvzi的博客 1135

qsort函数 - (Quick Sort)【快速排序的使用方法】

是c语言中一种用于排序的函数,这种方法也叫作快速排序法。它与冒泡排序不同,冒泡排序是一种算法,而qsort是c语言中编译器函数库自带的排序函数,存在于stdlib.h文件中。qsort函数可以根据使用者的不同需求快速的实现不同数据的排序。

小侯宝的博客 612
上一篇: 踏入c语言的世界
下一篇: 模拟实现字符串操作函数
Obto-
博客等级 码龄5年 721粉丝 58原创
评论 20
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Obto-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值