八大算法排序@计数排序(C语言版本)

目录

  • 计数排序
    • 概念
    • 算法思想
    • 算法步骤
    • 代码实现
    • 时间复杂度
    • 空间复杂度
    • 特性总结

计数排序

概念

  计数排序(Counting Sort)是一种线性时间复杂度的排序算法,适用于排序一定范围内的整数数组。它利用了输入序列的数值范围来确定每个元素在输出序列中的位置。




算法思想

  主要思路是找出待排序数组的最大值和最小值,确认原数组的范围range,然后申请一有range个空间大小的数组并且数组内各个元素初始化为0,称之为计数数组。将原数组中的数映射到计数数组中,最终通过计数数组中的元素的数值,判断映射过来的数出现了多少次,以及原数组中的顺序情况。我们拿实现升序的计数排序来进行模拟演变。
如下,是初始状态图:

在这里插入图片描述

其中, arr1 = { 6 , 4 , 3 , 9 , 2 ,1 , 5 , 7 , 8 }是待排序的数组,变量maxi 和 mini 分别用来存放数组中最大的元素和最小的元素的下标。range是数组arr1的范围大小。



第一步:

第一步

找出原数组中的最大值和最小值的下标,通过下标算出原数组数据的范围range。再使用malloc函数,申请range个空间的计数数组retArr[range];



第二步:

通过迭代循环,将原数组一个个的映射到计数数组中,如下:

映射过程
需要注意的问题有:
1、偏移量的问题。映射关系要减去原数组的最小值,也是计数数组下标的问题。比如有个数组范围是10,但是最小值是100,最大值是109。比如数组中有个数105,要将它映射到计数数组中,直接将105映射到计数数组的话,那么计数数组就得开到有106个空间,这就造成了浪费。将105减去最小值100,这样映射到计数数组中的下标就是5,一样能够解决问题,这就避免了空间的浪费。

2、初始化问题。malloc动态申请的空间,没有初始化时数组内的各个元素都是随机值,而计数排序的关键就是对原数组中数据的大小、出现次数进行统计。所以对于申请开辟出来的计数数组中的初始值,我们要初始化好,一般都初始化为0,方便。也可以初始化为其他数,但是后面要消掉这个偏移量。

3、内存泄露问题。动态申请的空间,最后时得主动释放空间,要不然会造成内存泄露。

4、类型问题。计数排序只适用于整形数据的排序。字符类型要比较类型也不是不可以,但是要考虑ASCII码值的转换,比如字符 ‘1’ - 字符 ‘0’ 就等于整型数据1啦。但是像字符串、浮点型则不适用,因为字符串的比较大小的规则、浮点型的精确度问题,都不适用计数排序来排序。字符串和浮点型可以考虑使用其他的排序方法,如快速排序和归并排序等。



最后,我们得到了一个将原数组全部映射完到计数数组的,一个统计数组retArr。我们再通过计数数组retArr,复原出原数组,同时也就实现了对原数组的排序。
最终

以上,便是对计数排序的大体图文介绍,下面用文字表述以上思路。




算法步骤

确定范围: 找出待排序数组中的最大值和最小值,确定数值范围。
计数:     创建一个辅助数组(计数数组),长度为数值范围的大小,用于统计原始数组中每个元素出现的次数。
累加计数: 对计数数组进行累加操作,使得每个位置上的值表示小于或等于该位置值的元素个数。
输出:     根据原始数组的值在计数数组中找到对应的位置,将元素放置到输出数组中。


接下来,就用代码来实现吧。




代码实现

// 时间复杂度:O(N+range)
// 空间复杂度:O(range)
// 只适用于整形,如果是浮点数或者字符串排序,还得用比较排序
void CountSort(int* a, int n)
{
	int max = a[0];
	int min = a[0];
	// 找出原数组中的最大值和最小值
	for (int i = 1; i < n; i++)
	{
		if (a[i] > max)		max = a[i];
		if (a[i] < min)		min = a[i];
	}
	// 算出原数组的范围
	int range = max - min + 1;
	// 申请开辟range个大小的空间
	int* retArr = (int*)malloc(sizeof(int) * range);
	memset(retArr, 0, sizeof(int) * range);	// 注意,要对该空间初始化为0,才能对数组a进行计数!!!!,否则数组自身随机值会导致计数的失败

	// 判断申请空间是否成功
	if (retArr == NULL)
	{
		printf("空间扩容失败\r\n");
		exit(-1);
	}

	// 将原数组映射到计数数组中,进行统计
	for (int i = 0; i < n; i++)
	{
		retArr[a[i] - min] += 1;
	}

	// 通过计数数组复原原数组的元素,同时完成排序的效果
	int index = 0;
	for (int j = 0; j < range; j++)
	{
		while (retArr[j]--)
		{
			a[index++] = j + min;
		}
	}
	
	free(retArr);
}

以上便是计数排序的代码实现,具体可以看着代码一点点意会,此处不做多加讲解。需要注意的便是下标的迭代问题了。




时间复杂度

O(N+range),其中N是数组元素个数,range是辅助计数数组的范围。
当N>>range时,时间复杂度为O(N);
当range>>N时,时间复杂度为O(range);
当N和range相近时,时间复杂度为O(N)或O(range)。

注:“ >> ” 是远大于的意思
算计数排序时间复杂度的思想:
首先要遍历一遍原数组找出最大、最小值,需要N步;
其次需要将计数数组依次映射复原原数组,需要range步。至于比如说有的计数数组的元素值为3,那么该元素得迭代3次,对于常数次的动作,计算时间复杂度时不计入。



空间复杂度

O(range)

计数排序得向内存申请range个空间。所以空间复杂度为O(range)

注:“ range ” 是原数组的数值范围




特性总结

1、只适合整形数据的排序,字符、字符串或浮点型等都不适用。
2、时间复杂度:O(N+range)
3、空间复杂度:O(range)
4、稳定性:稳定

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

dmetl5授权查看与更新

1.查看dmetl5授权到期时间 需要登录管理端&#xff0c;菜单栏选择“管理”-“license管理”即可查看授权到期时间。如下图&#xff1a; 2.dmetl5更新授权的方法 dmetl5的<安装目录>\scheduler\config路径下&#xff0c;默认会有一个trail.key的文件&#xff0c;删除后&am…

24、Web攻防——通用漏洞SQL注入MYSQL跨库ACCESS偏移

文章目录 一、SQL注入原理   脚本代码在与数据库进行数据通讯时&#xff08;从数据库取出相关数据进行页面显示&#xff09;&#xff0c;使用预定义的SQL查询语句进行数据查询。能通过参数传递自定义值来实现SQL语句的控制&#xff0c;执行恶意的查询操作&#xff0c;例如查询…

服务异步通讯---RabbitMQ实用篇

目录 一、初识MQ 一、同步调用 1、同步通讯和异步通讯 2、同步调用的问题 3.同步调用总结 二、异步调用 1、优势&#xff1a; ​编辑 2、异步总结 二、什么是MQ 一、RabbitMQ快速入门 1、RabbitMQ的结构和概念 2、常见消息模型 2.1、基础消息队列模型 2.2、总结 二…

高效管理版本控制,Cornerstone 4 for Mac助您成为SVN专家

在软件开发和团队合作中&#xff0c;版本控制是一个至关重要的环节。为了帮助开发者更加高效地管理和控制代码版本&#xff0c;Cornerstone 4 for Mac应运而生。作为一款功能强大的SVN&#xff08;Subversion&#xff09;管理工具&#xff0c;Cornerstone 4 for Mac为Mac用户提…

IO进程线程 day2

1.使用fread、fwrite完成两个文件的拷贝 #include <stdio.h> #include <string.h> #include <stdlib.h> int main(int argc, const char *argv[]) {//判断输入是否合法if(argc>3){printf("输入不合法\n");return -1;}//定义两个文件指针&#…

低代码搭建,助力批发零售行业解决方案的快速实现

引言 随着技术的快速发展&#xff0c;低代码技术作为一种高效的业务解决方案&#xff0c;正日益在批发零售行业中展现其巨大的应用潜力。其所带来的快速搭建、灵活性和成本效益&#xff0c;对于现代批发零售业务的管理和发展具有重要意义。 本文旨在探讨低代码技术在批发零售…

努力打工的你存到钱了?2024新蓝海创业项目/适合普通人创业项目

为什么有钱人那么有钱&#xff1f;是他们够努力吗&#xff1f;有一位网友回答是这样回答的&#xff1a; “从小到大我所接触到的一切成功&#xff0c;他的基础都是努力&#xff0c;甚至于奉承时的吃得苦上苦方为人上人。但是那天我的三观出现了认知错误&#xff0c;光靠努力赚…

【番外】【Airsim in Windows WSL2-Ubuntu20.04-ROS】环境配置大全

【番外】【Airsim in Windows & WSL2-Ubuntu20.04-ROS】环境配置大全 【前言&#xff08;可省略不看&#xff09;】1.在windows上面部署好UE4AirSim联合仿真环境2.在windows上面部署wsl2系统以及在wsl2上面部署ubuntu系统3.安装好ubuntu系统之后&#xff0c;目前只能在命令…

手敲MyBatis(十四章)-解析含标签的动态SQL语句

1.前言 这一章主要的就是要解析动态标签里的Sql语句&#xff0c;然后进行条件语句的拼接&#xff0c;动态标签实现了trim和if标签&#xff0c;所以Sql节点就要加上TrimSqlNode和ifSqlNode&#xff0c;我们最终要获取Sql源&#xff0c;动态Sql语句需要一些处理&#xff0c;所以…

AI原生应用开发“三板斧”亮相WAVE SUMMIT+2023

面对AI应用创新的风口跃跃欲试&#xff0c;满脑子idea&#xff0c;却苦于缺乏技术背景&#xff0c;不得不望而却步&#xff0c;这曾是许多开发者的苦恼&#xff0c;如今正在成为过去。 12月28日&#xff0c;WAVE SUMMIT深度学习开发者大会2023在北京举办。百度AI技术生态总经理…

文件监控软件丨文件权限管理工具

文件已经成为企业最重要的资产之一。然而&#xff0c;文件的安全性和完整性经常受到威胁&#xff0c;如恶意软件感染、人为误操作、内部泄密等。 为了确保文件的安全&#xff0c;文件监控软件应运而生。本文将深入探讨文件监控软件的概念、功能、应用场景和未来发展等方面。 文…

Grafana UI 入门使用

最近项目上需要使用Grafana来做chart&#xff0c;因为server不是我在搭建&#xff0c;所以就不介绍怎么搭建grafana server&#xff0c;而是谈下怎么在UI上具体操作使用了。 DOCs 首先呢&#xff0c;贴一下官网doc的连接&#xff0c;方便查询 Grafana open source documenta…

【数据库原理】(6)关系数据库的关系操作集合

基本关系操作 关系数据操作的对象都是关系,其操作结果仍为关系,即集合式操作。关系数据库的操作可以分为两大类&#xff1a;数据查询和数据更新。这些操作都是基于数学理论&#xff0c;特别是集合理论。下面是对这些基本操作的解释和如何用不同的关系数据语言来表达这些操作的…

Objects are not valid as a React child (found: object with keys {name}).

在jsx中可以嵌套表达式&#xff0c;将表达式作为内容的一部分&#xff0c;但是要注意&#xff0c;普通对象不能作为子元素&#xff1b;但是数组&#xff0c;react元素对象是可以的 如下&#xff1a;不能将stu这个对象作为子元素放 function App() {const myCal imgStyleconst…

OSG-纹理映射(二)

2.6 Mipmap纹理映射 在一个动态的场景中&#xff0c;当一个纹理对象迅速远离视点时&#xff0c;纹理图像必须随着被投影的图像一起缩小。为了实现这种效果&#xff0c;可以通过对纹理图像进行过滤&#xff0c;适当对它进行缩小&#xff0c;以使它映射到物体的表面时不会产生抖动…

Android 串口协议

前言 本协议是 Android 应用端与主控板之间的通信协议&#xff0c;是串行通信协议。 协议要求同一时间只能有两个通讯端点在相互通讯&#xff0c;采用小端传输数据。 硬件层基于RS485协议&#xff0c;采取半双工&#xff0c;一主多从的通讯模式。Android定义为主机&#xff0c…

DataGear 4.7.0 发布,数据可视化分析平台

DataGear 4.7.0 发布&#xff0c;严重漏洞和BUG修复&#xff0c;具体更新内容如下&#xff1a; 新增&#xff1a;HTTP数据集新增【编码请求地址】支持&#xff0c;可用于解决请求地址中文乱码问题&#xff1b;新增&#xff1a;新增数据源密码加密存储支持&#xff08;开启需设…

怎么有效利用HTTPS协议

HTTPS的发展史可以追溯到早期的互联网时代&#xff0c;当时HTTP协议被广泛使用&#xff0c;但由于通信过程是明文的&#xff0c;导致用户的敏感信息容易被截取和窃取。为了解决这个问题&#xff0c;HTTPS协议应运而生。 HTTPS是在HTTP协议的基础上加入了传输层安全协议&#x…

深挖小白必会指针笔试题<一>

目录 引言 关键解决办法&#xff1a; 学会画图确定指向关系 例题一&#xff1a; 画图分析&#xff1a; 例题二&#xff1a; 画图分析&#xff1a; 例题三&#xff1a; 注&#xff1a;%x是按十六进制打印 画图分析&#xff1a; 例题四&#xff1a; 画图分析&…

基于Java+SpringMvc+Vue求职招聘系统详细设计实现

基于JavaSpringMvcVue求职招聘系统详细设计实现 &#x1f345; 作者主页 专业程序开发 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; 文章目录 基于JavaSpringMvcVue求职招聘系统详细设计实现一、前言介…