【排序算法】 计数排序(非比较排序)详解!了解哈希思想!

在这里插入图片描述

🎥 屿小夏 : 个人主页
🔥个人专栏 : 算法—排序篇
🌄 莫道桑榆晚,为霞尚满天!

文章目录

  • 📑前言
  • 🌤️计数排序的概念
    • ☁️什么是计数排序?
    • ☁️计数排序思想
      • ⭐绝对映射
      • ⭐相对映射
  • 🌤️计数排序的实现
    • ☁️实现思路
    • ☁️代码实现
    • ☁️代码解析
  • 🌤️计数排序特性总结
    • ☁️时间复杂度:
    • ☁️空间复杂度
    • ☁️稳定性
    • ☁️适用性限制
    • ☁️不适用于大规模数据
    • ☁️总结
  • 🌤️全篇总结

📑前言

什么是计数排序?计数排序的思想是什么?它是如何实现的?

本文会对计数排序进行由浅入深的探究,让你彻底掌握计数排序!

🌤️计数排序的概念

☁️什么是计数排序?

​ 计数排序又称为鸽巢原理,是对哈希直接定址法的变形应用。

​ 统计每个元素出现的次数,然后根据元素的大小顺序将它们放入正确的位置。

☁️计数排序思想

计数排序是一种小众的排序,它适合于数据密集的场景,按最大数的数值来开空间。

⭐绝对映射

假设现有一组数据,最大的数据是1000,那么便会开一千个大小的空间,这种属于绝对映射,在极端的场景下,极易造成空间上的浪费,比如现在有5,99,88,1000,8888,452,635,82,777,555,只有10个数但是最大的数是8888因此要开8888大小的空间,剩余的空间全部都浪费了。

⭐相对映射

因此绝大多数情况下,都会使用相对映射。

具体的步骤如下:

  1. 找出待排序数组中的最大值和最小值,并创建一个计数数组,长度为最大值和最小值之差加1。
  2. 遍历待排序数组,统计每个元素出现的次数,并将次数存储在计数数组的相应位置上。
  3. 对计数数组进行累加操作,得到每个元素在排序后数组中的最终位置。
  4. 创建一个与待排序数组长度相同的临时数组,用于存储排序后的结果。
  5. 从后向前遍历待排序数组,根据计数数组中每个元素的值,将元素放入临时数组的相应位置上。
  6. 将临时数组中的元素复制回待排序数组,完成排序。

在这里插入图片描述

🌤️计数排序的实现

☁️实现思路

  1. 找到数组中的最小值和最大值,以确定计数数组的大小。
  2. 然后,根据最小值和最大值计算计数数组的大小,并分配内存空间。
  3. 接下来,将计数数组的所有元素初始化为0。
  4. 然后,遍历原数组,统计每个元素出现的次数,将统计结果保存在计数数组中。
  5. 接着,使用两个循环,将计数数组中的元素按照次数依次放回原数组中。
  6. 最后,释放计数数组的内存空间。

☁️代码实现

//计数排序
void CountSort(int* a, int n)
{
	int min = a[0];
	int max = a[0];
	for (int i = 0; i < n; i++)
	{
		if (a[i] < min)
		{
			min = a[i];
		}
		if (a[i] > max)
		{
			max = a[i];
		}
	}
	int range = max - min + 1;
	int* count = (int*)malloc(sizeof(int) * range);
	if (count == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	memset(count, 0, sizeof(int) * range);
	for (int i = 0; i < n; i++)
	{
		count[a[i] - min]++;
	}
	int j = 0;
	for (int i = 0; i < range; i++)
	{
		while (count[i]--)
		{
			a[j++] = i + min;
		}
	}
}

☁️代码解析

  1. 寻找最小值和最大值: 首先,通过循环遍历输入数组 a,找到数组中的最小值 min 和最大值 max。这是为了确定排序范围。
  2. 确定排序范围: 计算排序范围 range,即 (max - min + 1),这表示需要排序的整数范围。
  3. 创建计数数组: 使用 malloc 函数为计数数组 count 分配内存,该数组的大小是排序范围 range。计数数组用于存储每个整数在输入数组中出现的次数。
  4. 初始化计数数组: 使用 memset 函数将计数数组 count 中的所有元素初始化为0。
  5. 计数: 遍历输入数组 a,对于每个整数 a[i],将其减去 min 的值作为索引,然后在计数数组中对应索引位置的值加1。这一步会统计每个整数在输入数组中出现的次数。
  6. 重构排序数组: 使用两个循环,首先遍历计数数组 count,然后在内部循环中,根据计数数组中的值,将相应数量的整数值还原到原始输入数组 a。这将完成排序过程。

🌤️计数排序特性总结

☁️时间复杂度:

计数排序的时间复杂度为 O(n+k),其中 n 是输入数组的大小,k 是整数的范围。它具有线性时间复杂度的优点,适用于整数排序,特别是当整数范围相对较小且分布均匀时。

☁️空间复杂度

计数排序的空间复杂度取决于整数范围,为 O(k)。因此,它需要额外的空间来存储计数数组,当整数范围较大时可能会占用较多内存。

☁️稳定性

计数排序是一种稳定的排序算法。稳定性意味着具有相同值的元素在排序后仍保持相对顺序不变。在计数排序中,具有相同值的元素会按照它们在输入数组中的顺序被放置在输出数组中。

☁️适用性限制

计数排序仅适用于整数排序,特别是当整数范围相对较小且分布均匀时。它不适用于排序包含负数或浮点数的数组。此外,如果整数范围过大,可能会导致内存占用过多。

☁️不适用于大规模数据

尽管计数排序具有线性时间复杂度的优点,但它对于大规模数据集的排序可能并不理想。当整数范围非常大且分布不均匀时,计数排序的性能可能会受到限制。

☁️总结

计数排序适用于特定范围内的整数排序,并且在这种情况下具有稳定的性能表现。然而,在应用计数排序时,需要仔细考虑整数范围和数据集的分布情况,以确保不会出现内存占用过大或性能下降的情况。

🌤️全篇总结

本章专门对计数排序从概念到实现,进行了细致入微的讲解,期望对你理解掌握计数有所帮助!

看到这里希望给博主留个:👍点赞🌟收藏⭐️关注!
你们的点赞就是博主更新最大的动力!
有问题可以评论或者私信呢秒回哦。

在这里插入图片描述

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

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

相关文章

安全第一!速卖通测评补单稳定的系统注意事项大盘点

对新卖家而言&#xff0c;测评并非可耻之事&#xff0c;反而是无法起步、耗费自身时间才是真正的可耻。由于速卖通新店几乎无法获得任何活动的支持&#xff0c;流量也基本没有&#xff0c;因此要在90天内达成60单的业绩对于许多卖家来说都是一项挑战。因此&#xff0c;通过快速…

将一个Series序列转化为数据框Dataframe格式Series.to_frame()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 将一个Series序列 转化为Dataframe格式 Series.to_frame() [太阳]选择题 关于以下代码的说法中正确的是? import pandas as pd s pd.Series([1,2],name"myValue") print("【显…

了解数据库设计,轻轻松松提高工作效率

每个应用程序&#xff0c;无论大小&#xff0c;最终都需要一个数据库来持久保存所有重要数据。对此没有任何争论&#xff01; 什么是数据库设计&#xff1f; 数据库设计是帮助创建、实施和维护企业数据管理系统的一系列步骤的集合。设计数据库的主要目的是为所建议的数据库系统…

单元测试,集成测试,系统测试的区别是什么?

实际的测试工作当中&#xff0c;我们会从不同的角度对软件测试的活动进行分类&#xff0c;题主说的“单元测试&#xff0c;集成测试&#xff0c;系统测试”&#xff0c;是按照开发阶段进行测试活动的划分。这种划分完整的分类&#xff0c;其实是分为四种“单元测试&#xff0c;…

锐捷RG-EW1200G登录绕过漏洞复现

文章目录 锐捷RG-EW1200G登录绕过漏洞复现0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.复现 0x06 修复建议 锐捷RG-EW1200G登录绕过漏洞复现 0x01 前言 免责声明&#xff1a;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、…

vue-admin-template 安装遇到的问题

vue-element-admin 是一个后台前端解决方案&#xff0c;它基于 vue 和 element-ui实现。 参考文档&#xff1a; 官网&#xff1a; https://panjiachen.github.io/vue-element-admin-site/zh/guide/#%E5%8A%9F%E8%83%BD遇到的问题&#xff1a; npm ERR! Error while executing…

基于JAVA+SpringBoot+Vue的前后端分离的大学生创新作品审核平台

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 随着大学教育的发展&a…

我的1024创作纪念日

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 机缘 起初我并没有写博客这个习惯&#xff…

Ubuntu20.04安装CUDA、cuDNN、tensorflow2可行流程(症状:tensorflow2在RTX3090上运行卡住)

最近发现我之前在2080ti上运行好好的代码&#xff0c;结果在3090上运行会卡住很久&#xff0c;而且模型预测结果完全乱掉&#xff0c;于是被迫研究了一天怎么在Ubuntu20.04安装CUDA、cuDNN、tensorflow2。 1.安装CUDA&#xff08;包括CUDA驱动和CUDA toolkit&#xff0c;注意此…

CN考研真题知识点二轮归纳(2)

持续更新&#xff0c;上期目录&#xff1a; CN考研真题知识点二轮归纳&#xff08;1&#xff09;https://blog.csdn.net/jsl123x/article/details/134095044?spm1001.2014.3001.5501 1.DCHP 动态主机配置协议&#xff0c;常用于给主机动态分配IP地址&#xff0c;它提供即插即…

为什么边缘计算是能源行业缺失的一环

关键要点 展望未来&#xff0c;边缘计算将使能源部门能够更好地应对不断增长的能源需求的挑战&#xff0c;提高资源利用率&#xff0c;并实现更可持续的能源生态系统。 能源行业正在经历重大变革&#xff0c;因为它面临着许多挑战&#xff0c;例如整合可再生能源、电力需求激增…

物联网整体框架有哪些层面?

物联网是当前非常火热的话题&#xff0c;各个行业对物联网的关注和投入力度也很大&#xff0c;一些互联网巨头都在紧锣密鼓的布局物联网产业&#xff0c;抢占市场先机。 物联网的整体构架大致可以分为以下四个层面&#xff1a; 1.感知识别层 感知层是物联网整体架构的基础&…

jenkins实践篇(2)—— 自动打tag的可回滚发布模式

大家好&#xff0c;我是蓝胖子&#xff0c;在上一篇我简单介绍了如何基于特定分支做自动编译和发布&#xff0c;在生产环境中&#xff0c;为了更加安全和快速回滚&#xff0c;我采取的是通过对代码打tag的方式来进行部署&#xff0c;下面我将详细介绍整个发布过程的逻辑。 发布…

海外问卷调查是什么项目?一篇文章详细介绍!

大家好&#xff0c;我是橙河网络&#xff0c;是一家问卷公司的老板&#xff0c;做海外问卷项目已经2年时间了&#xff0c;这篇文章就简单介绍一下海外问卷调查是什么项目。 海外问卷调查&#xff0c;简单来说&#xff0c;就是国外的商业公司、对外发放的有偿市场调查问卷&…

【Unity实战】最全面的库存系统(三)

文章目录 先来看看最终效果前言新增脚本获取唯一ID保存和加载保存地面物品将玩家快捷栏和背包合并快捷栏物品显示完结先来看看最终效果 前言 本期紧跟着上期,继续来完善我们的库存系统,实现物品背包仓库数据的存储和加载功能 新增脚本获取唯一ID 新增脚本,自定义控制只读…

晨控CK-GW08系列网关控制器与CODESYS软件MODBUSTCP通讯手册

晨控CK-GW08系列是一款支持标准工业通讯协议ModbusTCP的网关控制器,方便用户集成到PLC等控制系统中。系统还集成了8路读写接口&#xff0c;用户可通过通信接口使用Modbus TCP协议对8路读写接口所连接的读卡器进行相对独立的读写操作。 晨控CK-GW08系列网关控制器适用于本公司多…

NLP 模型中的偏差和公平性检测

一、说明 近年来&#xff0c;自然语言处理 &#xff08;NLP&#xff09; 模型广受欢迎&#xff0c;彻底改变了我们与文本数据交互和分析的方式。这些基于深度学习技术的模型在广泛的应用中表现出了卓越的能力&#xff0c;从聊天机器人和语言翻译到情感分析和文本生成。然而&…

机器学习 - 加油站数据分析

一、实验数据 数据集&#xff1a;“加油站数据.xls” 数据集介绍&#xff1a;该表记录了用户在11月和12月一天24小时内的加油信息&#xff0c;包括&#xff1a;持卡人标识&#xff08;cardholder&#xff09;、卡号&#xff08;cardno&#xff09;、加油站网点号&#xff08;n…

uni-app小程序使用vant

步骤一&#xff1a;安装 Vant Weapp # 通过 npm 安装 npm i vant/weapp -S --production# 通过 yarn 安装 yarn add vant/weapp --production# 安装 0.x 版本 npm i vant-weapp -S --production步骤二&#xff1a;在根目录下创建“wxcomponents”文件夹 步骤三&#xff1a;找…

Unity地面交互效果——2、动态法线贴图实现轨迹效果

Unity引擎动态法线贴图制作球滚动轨迹 大家好&#xff0c;我是阿赵。   之前说了一个使用局部UV采样来实现轨迹的方法。这一篇在之前的基础上&#xff0c;使用法线贴图进行凹凸轨迹的绘制。 一、实现的目标 先来回顾一下&#xff0c;上一篇最终我们已经绘制了一个轨迹的贴图…