学会快速排序库函数qsort的使用以及实现

news2024/10/6 14:29:58

  • qsort的使用
    • 使用细节一
    • 完成代码
  • qsort的实现(用冒泡排序)
    • 写法一
    • 写法二
    • 完整代码

qsort的使用

qsort函数的官方介绍: 点这里
在这里插入图片描述
qsort函数需要包含头文件<stdlib.h>
qsort函数有四个参数,逐一介绍
base:指向数组中要排序的第一个对象的指针,转换为void*
num:基数指向的数组中元素的个数。Size_t是一个无符号整型
size:数组中每个元素的字节大小。Size_t是一个无符号整型
compar:指向比较两个元素的函数的指针

这个函数被qsort反复调用以比较两个元素。这个函数的格式为
int compar (const void* p1, const void* p2);

这个函数需要做到为qsort提供参数。

返回值含义
小于0的值p1所指向的元素比p2所指向的元素“小”,需要排在p2前面
0p1所指向的元素和p2所指向的元素一样大
大于0的值p1所指向的元素比p2所指向的元素“大”,需要排在p2前面
补充说明在vs中这三个值一般是1、0、-1

使用细节一

浮点数无法直接比较大小,这里的实现方法需要牢牢掌握
先需要宏定义一个EPS,值为1e-7,这是哥非常非常小的值(1×10^-7),当俩浮点数之差的绝对值小于EPS时,可以代表这俩浮点数相等。

#include<stdio.h>
#include<stdlib.h>
#include<math.h>//fabs//绝对值

#define EPS 1e-7 //判断浮点数是否位于0的一个很小的邻域内[-EPS,EPS]内

typedef struct STU
{
	char name[10];
	int age;
	float TotalScore;
}Stu;

int CmpFloat(const void* p1, const void* p2)
{
	if (fabs((*(float*)p1 - (*(float*)p2)) <= EPS))
	{
		return 0;
	}
	else if ((*(float*)p1 - (*(float*)p2) > EPS))
	{
		return 1;
	}
	else
	{
		return -1;
	}
}

void TestFloat()
{
	float arr[] = { 1.2f,3.4f,2.8f,8.4f,6.3f };
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]), CmpFloat);
}

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

完成代码

#define _CRT_SECURE_NO_WARNINGS 1

//库函数qsort的使用
//void qsort (void* base, 
			// size_t num, 
			// size_t size,
			// int (*compar)(const void*, const void*));
//char int float struct

#include<stdio.h>
#include<stdlib.h>//qsort
#include<math.h>//fabs//绝对值

#define EPS 1e-7 //判断浮点数是否位于0的一个很小的邻域内[-EPS,EPS]内

typedef struct STU
{
	char name[10];
	int age;
	float TotalScore;
}Stu;

int CmpInt(const void* p1, const void* p2)
{
	return ((*(int*)p1) - (*(int*)p2));
}

void TestInt()
{
	int arr[] = { 7,5,9,1,3,2,4,6,8,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]), CmpInt);
}

int CmpChar(const void* p1, const void* p2)
{
	return ((*(char*)p1) - (*(char*)p2));
}

void TestChar()
{
	char arr[] = "AKRZXIY";
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]), CmpChar);
}

int CmpFloat(const void* p1, const void* p2)
{
	if (fabs((*(float*)p1 - (*(float*)p2)) <= EPS))
	{
		return 0;
	}
	else if ((*(float*)p1 - (*(float*)p2) > EPS))
	{
		return 1;
	}
	else
	{
		return -1;
	}
}

void TestFloat()
{
	float arr[] = { 1.2f,3.4f,2.8f,8.4f,6.3f };
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]), CmpFloat);
}

int CmpStructName(const void* p1, const void* p2)
{
	return strcmp((*(Stu*)p1).name,(*(Stu*)p2).name);
}

int CmpStructAge(const void* p1, const void* p2)
{
	return ((*(Stu*)p1).age - (*(Stu*)p2).age);
}

int CmpStructTotal(const void* p1, const void* p2)
{
	if (fabs((*(Stu*)p1).TotalScore - (*(Stu*)p2).TotalScore) <= EPS)
	{
		return 0;
	}
	else if (((*(Stu*)p1).TotalScore - (*(Stu*)p2).TotalScore) > EPS)
	{
		return 1;
	}
	else
	{
		return -1;
	}
}

void TestStruct()
{
	Stu stu[3] = { {"bb",10,300},{"aa",30,200},{"cc",20,100} };
	int sz = sizeof(stu) / sizeof(stu[0]);
	qsort(stu, sz, sizeof(stu[0]), CmpStructName);
	qsort(stu, sz, sizeof(stu[0]), CmpStructAge);
	qsort(stu, sz, sizeof(stu[0]), CmpStructTotal);
}

int main()
{
	TestInt();
	TestChar();
	TestFloat();
	TestStruct();
	return 0;
}

qsort的实现(用冒泡排序)

写法一

void Swap(char* buf1, char* buf2, int size)//交换arr[j],arr[j+1]这两个元素
{
	int i = 0;
	char tmp = 0;
	for (i = 0; i < size; i++)
	{
		tmp = *buf1;
		*buf1 = *buf2;
		*buf2 = tmp;
		buf1++;
		buf2++;
	}
}

void bubble_sort(void* base, int num, int size, int (*cmp)(const void*, const void*))
{
	int  i = 0;
	//趟数
	for (i = 0; i < num - 1; i++)
	{
		int j = 0;
		//一趟内部比较的对数
		for (j = 0; j < num - 1 - i; j++)
		{
			//假设需要升序cmp返回>0,交换
			if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0)//两个元素比较,需要将arr[j],arr[j+1]的地址要传给cmp
			{
				//交换
				Swap((char*)base + j * size, (char*)base + (j + 1) * size, size);
			}
		}
	}

}

写法二

void Swap(void* base, int j, size_t size)
{
	int i = 0;
	for (i = 0; i < size; i++)
	{
		char tmp = *((char*)base + j * size + i);
		*((char*)base + j * size + i) = *((char*)base + (j+1) * size + i );
		*((char*)base + (j+1) * size + i) = tmp;
	}
}

void BubbleSort(void* base, size_t num, size_t size, int (*compar)(const void*, const void*))
{
	int i = 0;
	for (i = 0; i < num - 1; i++)
	{
		int j = 0;
		for (j = 0; j < num - 1 - i; j++)
		{
			
			if (compar(((char*)base + j * size), ((char*)base + (j + 1) * size)) > 0)
			{
				Swap(base,j,size);
			}
		}
	}
}

完整代码

#define _CRT_SECURE_NO_WARNINGS 1

//库函数qsort的实现(用冒泡排序的思想)
//void qsort (void* base, 
			// size_t num, 
			// size_t size,
			// int (*compar)(const void*, const void*));
//char int float struct

#include<stdio.h>
#include<stdlib.h>//BubbleSort
#include<math.h>//fabs//绝对值

#define EPS 1e-7 //判断浮点数是否位于0的一个很小的邻域内[-EPS,EPS]内

typedef struct STU
{
	char name[10];
	int age;
	float TotalScore;
}Stu;

//写法一
//void Swap(char* buf1, char* buf2, int size)//交换arr[j],arr[j+1]这两个元素
//{
//	int i = 0;
//	char tmp = 0;
//	for (i = 0; i < size; i++)
//	{
//		tmp = *buf1;
//		*buf1 = *buf2;
//		*buf2 = tmp;
//		buf1++;
//		buf2++;
//	}
//}
//
//void bubble_sort(void* base, int num, int size, int (*cmp)(const void*, const void*))
//{
//	int  i = 0;
//	//趟数
//	for (i = 0; i < num - 1; i++)
//	{
//		int j = 0;
//		//一趟内部比较的对数
//		for (j = 0; j < num - 1 - i; j++)
//		{
//			//假设需要升序cmp返回>0,交换
//			if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0)//两个元素比较,需要将arr[j],arr[j+1]的地址要传给cmp
//			{
//				//交换
//				Swap((char*)base + j * size, (char*)base + (j + 1) * size, size);
//			}
//		}
//	}
//
//}

//写法二
void Swap(void* base, int j, size_t size)
{
	int i = 0;
	for (i = 0; i < size; i++)
	{
		char tmp = *((char*)base + j * size + i);
		*((char*)base + j * size + i) = *((char*)base + (j+1) * size + i );
		*((char*)base + (j+1) * size + i) = tmp;
	}
}

void BubbleSort(void* base, size_t num, size_t size, int (*compar)(const void*, const void*))
{
	int i = 0;
	for (i = 0; i < num - 1; i++)
	{
		int j = 0;
		for (j = 0; j < num - 1 - i; j++)
		{
			
			if (compar(((char*)base + j * size), ((char*)base + (j + 1) * size)) > 0)
			{
				Swap(base,j,size);
			}
		}
	}
}

int CmpInt(const void* p1, const void* p2)
{
	return ((*(int*)p1) - (*(int*)p2));
}

void TestInt()
{
	int arr[] = { 7,5,9,1,3,2,4,6,8,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	BubbleSort(arr, sz, sizeof(arr[0]), CmpInt);
}

int CmpChar(const void* p1, const void* p2)
{
	return ((*(char*)p1) - (*(char*)p2));
}

void TestChar()
{
	char arr[] = "AKRZXIY";
	int sz = sizeof(arr) / sizeof(arr[0]);
	BubbleSort(arr, sz, sizeof(arr[0]), CmpChar);
}

int CmpFloat(const void* p1, const void* p2)
{
	if (fabs((*(float*)p1 - (*(float*)p2)) <= EPS))
	{
		return 0;
	}
	else if ((*(float*)p1 - (*(float*)p2) > EPS))
	{
		return 1;
	}
	else
	{
		return -1;
	}
}

void TestFloat()
{
	float arr[] = { 1.2f,3.4f,2.8f,8.4f,6.3f };
	int sz = sizeof(arr) / sizeof(arr[0]);
	BubbleSort(arr, sz, sizeof(arr[0]), CmpFloat);
}

int CmpStructName(const void* p1, const void* p2)
{
	return strcmp((*(Stu*)p1).name, (*(Stu*)p2).name);
}

int CmpStructAge(const void* p1, const void* p2)
{
	return ((*(Stu*)p1).age - (*(Stu*)p2).age);
}

int CmpStructTotal(const void* p1, const void* p2)
{
	if (fabs((*(Stu*)p1).TotalScore - (*(Stu*)p2).TotalScore) <= EPS)
	{
		return 0;
	}
	else if (((*(Stu*)p1).TotalScore - (*(Stu*)p2).TotalScore) > EPS)
	{
		return 1;
	}
	else
	{
		return -1;
	}
}

void TestStruct()
{
	Stu stu[3] = { {"bb",10,300},{"aa",30,200},{"cc",20,100} };
	int sz = sizeof(stu) / sizeof(stu[0]);
	BubbleSort(stu, sz, sizeof(stu[0]), CmpStructName);
	BubbleSort(stu, sz, sizeof(stu[0]), CmpStructAge);
	BubbleSort(stu, sz, sizeof(stu[0]), CmpStructTotal);
}

int main()
{
	TestInt();
	//TestChar();
	//TestFloat();
	//TestStruct();
	return 0;
}

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

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

相关文章

趁同事上厕所的时间,看完了 Dubbo SPI 的源码,瞬间觉得 JDK SPI 不香了

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱敲代码的小黄&#xff0c;独角兽企业的Java开发工程师&#xff0c;CSDN博客专家&#xff0c;阿里云专家博主&#x1f4d5;系列专栏&#xff1a;Java设计模式、Spring源码系列、Netty源码系列、Kafka源码系列、JUC源码…

大数据平台测试-git常用操作(白盒测试基础)

一、前言 学习Git是非常有价值和重要的&#xff0c;无论是一个个人开发者还是在团队中进行协作开发。以下是一些学习Git的原因&#xff1a; 版本控制&#xff1a;Git是目前最流行的分布式版本控制系统&#xff0c;可以帮助你跟踪、管理和控制代码的版本。你可以轻松地回退到先…

gee架设教程

1:GameCenter 设置 1.1服务器控制 1.2 账号 1.3.1 配置向导 - 基本设置 1.3.2 配置向导 - 登录网关 1.3.3 配置向导 - 角色网关 1.3.4 配置向导 - 游戏网关 1.3.5 配置向导 - 登录服务器 1.3.6 配置向导 - 数据库服务器 1.3.7 配置向导 - 日志服务器 1.3.8 配置向导 - 主服务器…

SAP/ABAP(一)

一、什么是ERP ERP 是企业资源规划&#xff08;Enterprise Resource Planning&#xff09;的缩写&#xff0c;它指的是一种集成化的管理软件系统&#xff0c;用于协调企业内部各个部门的活动&#xff0c;并与外部供应商、客户以及其他利益相关方进行信息和业务流程的交互。 二、…

4.4.tensorRT基础(1)-模型推理时动态shape的具体实现要点

目录 前言1. 动态shape2. 补充知识总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程&#xff0c;之前有看过一遍&#xff0c;但是没有做笔记&#xff0c;很多东西也忘了。这次重新撸一遍&#xff0c;顺便记记笔记。 本次课程学习 tensorRT 基础-模型推理时动态 shape 的…

科大讯飞星火认知大模型实在是太牛逼了吧,可以和人类进行自然交流,解答问题,高效完成各领域认知智能需求。

星火认知大模型&#xff1a;探索人工智能的无限可能 在21世纪的今天&#xff0c;人工智能技术已经逐渐成为推动社会发展的重要力量。作为一种模拟人类智能的技术手段&#xff0c;人工智能在各个领域都展现出了强大的应用潜力。而在这个领域中&#xff0c;星火认知大模型无疑是…

awk用法--一次性匹配文件中的多个文本,保存成不同的参数

功能描述&#xff1a; 需要从某个文件中读取多个指标的数据&#xff0c;并保存下来&#xff0c;读取的时候需要一次性读取出多个数据&#xff0c;之后将数据写入到结果文件 代码示例 主要逻辑&#xff1a; 1、 匹配包含MemTotal的字符串&#xff0c;并将匹配到的行的倒数第二列…

【电子学会】2023年05月图形化三级 -- 绘制多彩五角星

绘制多彩五角星 1. 准备工作 &#xff08;1&#xff09;选择背景stars、角色Pencil&#xff1b; &#xff08;2&#xff09;将角色Penci的中心点设为笔尖。 2. 功能实现 &#xff08;1&#xff09;将画笔粗细设为3&#xff0c;画笔的颜色和初始位置自定义&#xff0c;绘制边…

【gis插件】arcgis插件界址点编号工具、C#实现思路

数据&#xff1a;界址点图层、宗地图层 要求&#xff1a;找出宗地对应的所有界址点号&#xff0c;对这些界址点号以J1开始按顺序排列 要找出宗地所对应的所有界址点号&#xff0c;这里只要执行一个标识 即可得到这样得到的结果。 难点在于对界址点的编号&#xff0c;经过检查…

c语言小项目——通讯录初阶

通讯录中阶&#xff1a;点这里 通讯录&#xff08;初阶&#xff09; 项目简介项目中遇到的难点1.给复杂结构体初始化错误写法正确写法 2.枚举和switch可以结合一下&#xff0c;方便查看switch的case中是什么功能&#xff0c;double3.ShowContact中printf的新认知4.FindByName加…

Vue 打包到生产环境部署后图标不见了

问题描述&#xff1a;打包完后部署到正式环境有些图标不显示&#xff0c;如下图&#xff0c;显示为小方块。 解决方案&#xff1a; 这个问题可能是vue-cli脚手架配置问题 在build/webpack.prod.conf.js中 把extract&#xff1a;true 改为 fasle&#xff0c;然后再重新build就…

商城-学习整理-基础-项目简介和分布式概念(一)

目录 前言&#xff1a;一、项目简介1、项目背景2、项目架构图 二、分布式基础概念1、微服务2、集群&分布式&节点3、远程调用4、负载均衡5、服务注册/发现&注册中心6、配置中心7、服务熔断&服务降级8、APP网关 前言&#xff1a; 该项目基于逆向工程进行开发&am…

nginx+lua+redis环境搭建(文末赋上脚本)

目录 需求背景 环境搭建后nginx和redis版本 系统环境 搭建步骤 配置服务器DNS 安装ntpdate同步一下系统时间 安装网络工具、编译工具及依赖库 创建软件包下载目录、nginx和redis安装目录 下载配置安装lua解释器LuaJIT 下载nginx NDK&#xff08;ngx_devel_kit&#xff09…

51单片机学习--独立按键控制LED

功能&#xff1a;按下K1时D1亮&#xff0c;松开时D1灭&#xff0c;P3_1对应K1 , P2_0对应D1 #include <REGX52.H>void main() {while(1) {if(P3_1 0) //按下K1{P2_0 0;}else{P2_0 1;}}} 按下按钮和松开按钮时会有抖动&#xff0c;所以需要用延时函数来避免抖动造成的…

C国演义 [第十章]

第十章 最佳买卖股票时机含冷冻期题目理解步骤dp数组递推公式初始化遍历方向 代码 买卖股票的最佳时机含手续费题目理解步骤dp数组递推公式初始化遍历方向 代码 最佳买卖股票时机含冷冻期 力扣链接 给定一个整数数组prices&#xff0c;其中第 prices[i] 表示第 i 天的股票价格…

瀚高数据库企业版V4单机版-安装手册(Windows)

目录 瀚高数据库企业版V4单机版-安装手册&#xff08;Windows&#xff09; 1. 环境准备 2. 软件安装 3.设置环境变量 4 配置数据库文件 瀚高数据库企业版V4单机版-安装手册&#xff08;Windows&#xff09; 1. 环境准备 ①.安装数据库之前&#xff0c;请确保vcredist_x6…

鸽了百万用户四年的赛博皮卡终于要来啦

作者 | Amy 编辑 | 德新 本月15号&#xff0c;特斯拉官方宣布&#xff0c;第一辆 赛博皮卡已在特斯拉得州工厂下线。 而就在本月初&#xff0c;马斯克还发推预热了一波&#xff0c;「开着赛博皮卡在奥斯汀&#xff08;特斯拉得州工厂所在地&#xff09;溜了一圈&#xff01…

网页动态表单 ,网页动态参数

有的时候因为参数太多 无法 一一 创建 所有采用动态创建 自己遇到的一个实际情况今天写个例子 <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>form demo</title><link rel"stylesheet" href&quo…

Windows查看电脑出厂时间

方法一&#xff1a;CMD命令查询 CMD输入命令 >systeminfoBIOS版本时间大概就是出厂时间

基于Mybatis-Plus的代码自动生成器

代码自动生成器 由于在普通业务开发中大多数增删改查操作都是重复的大量的&#xff0c;修改的内容也是相当的少&#xff0c;就如一个模版一样。所以在此构造一个基于Mybatis-Plus的代码生成器&#xff0c;旨在于快速生成项目结构和基础代码。 1、搭建环境 新建一个Springboo…