八大排序之——计数排序全方位剖析!(小白也能轻松看懂!)

目录

1. 计数排序的思想动图

 2. 从思想到代码的实现

 >1.创建临时数组

>2.统计次数

>3.排序

>4.简单版本

3. 是否可以优化呢~

4. 计数排序的时空复杂度

5.总结

计数排序的优点

计数排序的局限性

6、完结散花


                                                                                个人主页:秋风起,再归来~

                                                                                            数据结构与算法                             

                                                                       个人格言:悟已往之不谏,知来者犹可追

                                                                                        克心守己,律己则安!

1. 计数排序的思想动图

 2. 从思想到代码的实现

 >1.创建临时数组

我们先创建一个临时的数组tmp并且该数组的最大下标为原数组中元素的最大值里面的元素初始化为0

	//先遍历原数组找到最大值int max = a[0];for (int i = 1; i < n; i++){if (max < a[i]){max = a[i];}}//动态内存开辟max+1个int空间并初始化为0用callocint* tmp = (int)calloc(max+1, sizeof(int));if (tmp == NULL){perror("calloc fail!\n");return;}

>2.统计次数

然后遍历一遍原数组,原数组中出现哪个元素就在tmp数组中与该元素数值相同的下标对应的地方进行加加操作来记录该元素出现的次数。

	//统计次数for (int i = 0; i < n; i++){tmp[a[i]]++;}

>3.排序

最后我们再进行排序,记住tmp的下标对应原数组可能出现的元素,而里面的值对应该元素出现的次数,如果为0就说明该元素在原数组不存在。遍历tmp数组,将对应的下标覆盖原数组即可完成排序。

//排序
int j = 0;
for (int i = 0; i < max + 1; i++)//第一层循环遍历tmp数组
{while (tmp[i]--)//对应元素出现的次数{a[j++] = i;//tmp的下标对应的就是原数组可能出现的元素}
}
//释放资源,避免内存泄漏
free(tmp);
tmp = NULL;

>4.简单版本

好现在简单的计数排序就已经完成了

完整代码:

void CountSort(int* a,int n)
{//先遍历原数组找到最大值int max = a[0];for (int i = 1; i < n; i++){if (max < a[i]){max = a[i];}}//动态内存开辟max+1个int空间并初始化为0用callocint* tmp = (int*)calloc(max+1, sizeof(int));if (tmp == NULL){perror("calloc fail!\n");return;}//统计次数for (int i = 0; i < n; i++){tmp[a[i]]++;}//排序int j = 0;for (int i = 0; i < max + 1; i++)//第一层循环遍历tmp数组{while (tmp[i]--)//对应元素出现的次数{a[j++] = i;//tmp的下标对应的就是原数组可能出现的元素}}//释放资源,避免内存泄漏free(tmp);tmp = NULL;
}

3. 是否可以优化呢~

思考一下,如果我们的数据是这样的呢,如果还像之前那样开辟空间,是否会有大量的空间浪费呢?遍历的次数增大,是否有性能的降低呢~

所以,我们就可以这样取tmp的范围:

优化后代码: 

//先遍历原数组找到最大值
int max = a[0];
int min = a[0];
for (int i = 1; i < n; i++)
{if (max < a[i]){max = a[i];}if (min > a[i]){min= a[i];}
}
int range = max - min + 1;
//动态内存开辟max+1个int空间并初始化为0用calloc
int* tmp = (int*)calloc(range, sizeof(int));
if (tmp == NULL)
{perror("calloc fail!\n");return;
}

 关于下标与元素对应的问题,我们就可以采用相对映射的方法来解决(优化后代码)

优化后的完整代码:

void CountSort(int* a,int n)
{//先遍历原数组找到最大值int max = a[0];int min = a[0];for (int i = 1; i < n; i++){if (max < a[i]){max = a[i];}if (min > a[i]){min= a[i];}}int range = max - min + 1;//动态内存开辟max+1个int空间并初始化为0用callocint* tmp = (int*)calloc(range, sizeof(int));if (tmp == NULL){perror("calloc fail!\n");return;}//统计次数for (int i = 0; i < n; i++){tmp[a[i]-min]++;}//排序int j = 0;for (int i = 0; i < range; i++)//第一层循环遍历tmp数组{while (tmp[i]--)//对应元素出现的次数{a[j++] = i+min;//tmp的下标对应的就是原数组可能出现的元素}}//释放资源,避免内存泄漏free(tmp);tmp = NULL;
}

4. 计数排序的时空复杂度

>空间复杂度:除原数组外,计数排序额外开辟了一个大小为N的临时空间,所以计数排序的空间复杂度为O(N)。

>时间复杂度:遍历找最大最小值取范围的时间复杂度为O(N),遍历原数组统计次数的时间复杂度为O(N),而排序里面,虽有两层循环,但从思想和本质来看,它只不过是将原来的元素按顺序覆盖了原数组,其执行循环的次数任然为O(N),所以计数排序的时间复杂度为O(N).

5.总结

计数排序(Counting Sort)是一种非比较排序算法,它的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。

计数排序的优点

  1. 稳定性:计数排序是一种稳定的排序算法,即相等的元素在排序过程中不会改变相对位置。
  2. 时间复杂度低:在数据范围不是很大的情况下,计数排序的时间复杂度可以达到O(n),是非常高效的排序算法。
  3. 空间换时间:计数排序通过使用额外的空间来换取排序时间的大幅度降低,适合数据范围不大的情况。

计数排序的局限性

  1. 数据范围限制:当数据的范围非常大时,计数排序需要创建一个长度为最大值加一的数组,这将导致大量的空间浪费,因此它不适合数据范围很大的排序。
  2. 数据类型限制:计数排序只适用于整数排序,对于其他类型的数据(如字符串、浮点数等)则不适用。
  3. 空间复杂度较高:计数排序需要额外的存储空间来存储临时数组,当数据范围较大时,其空间复杂度会显著增加。

综上所述,计数排序在特定条件下(数据范围不大且为整数)是非常高效的排序算法,但在数据范围大或数据类型不匹配时则不适用。在实际应用中,需要根据具体的数据特征选择合适的排序算法。

6、完结散花

好了,这期的分享到这里就结束了~

如果这篇博客对你有帮助的话,可以用你们的小手指点一个免费的赞并收藏起来哟~

如果期待博主下期内容的话,可以点点关注,避免找不到我了呢~

我们下期不见不散~~

​​​​

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

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

相关文章

【腾讯云业务运营暑期实习面试题】

题目&#xff1a; &#xff08;全程大概50来分钟左右&#xff0c;面试官挺好的&#xff0c;不清楚的问题也在一直引导我&#xff0c;总体来说非常好&#xff0c;挺喜欢这个面试官的&#xff09; 1、自我介绍 2、讲讲文件的权限以及把目录下所有文件都修改 文件的权限 rwx --&…

动态规划(DFS -> 记忆化搜索 ->动态规划)

问题一&#xff1a; 首先看一个最经典的问题&#xff1a;上台阶问题。P1255 数楼梯 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 我们首先看一下&#xff0c;如何用DFS的方法进行解题。 假设我们要上到第5级台阶&#xff1a; 可以看出上到第五级台阶时&#xff0c;可能是…

oak相机使用oak官网方式标定

目录 一、depthai ROS驱动 一、depthai ROS驱动 &#xff08;1&#xff09;驱动下载地址&#xff1a;2. C 开发快速上手 — DepthAI Docs 0.3.0.0 documentation sudo apt install ./depthai_2.17.1_arm64.deb //运行 Python3 utilities/cam_test.py -mres 400 -cams rgb,m …

探索大模型:袋鼠云在 Text To SQL 上的实践与优化

Text To SQL 指的是将自然语言转化为能够在关系型数据库中执行的结构化查询语言&#xff08;简称 SQL&#xff09;。近年来&#xff0c;伴随人工智能大模型技术的不断进步&#xff0c;Text To SQL 任务的成功率显著提升&#xff0c;这得益于大模型的推理、理解以及指令遵循等能…

自闭症学校排名前十:为星儿点亮未来

在自闭症教育领域&#xff0c;有许多优秀的学校和机构为自闭症儿童提供着专业的帮助和支持。 星贝育园&#xff1a;以其独特的教育理念和个性化的教学方法脱颖而出。学校拥有一支经验丰富、富有爱心的教师团队&#xff0c;为孩子们提供全方位的关爱和教育。注重培养孩子的综合能…

手机通讯录大营救,恢复sim卡联系人的3个重要方法

在数字化世界的浩瀚海洋中&#xff0c;手机通讯录就像一艘承载着人际关系的生命之船。然而&#xff0c;当这艘船遭遇风浪&#xff0c;即sim卡上的联系人信息意外丢失时&#xff0c;我们该如何进行一场惊心动魄的大营救&#xff0c;找回那些珍贵的联系人呢&#xff1f;别担心&am…

Backend - C# 的日志Lognet4

目录 一、安装 log4net 插件 &#xff08;一&#xff09;作用 &#xff08;二&#xff09;操作 &#xff08;三&#xff09;注意 二、配置 &#xff08;一&#xff09;配置AssemblyInfo.cs &#xff08;二&#xff09;配置log4net.config 1. 创建log4net.config文件&#xff08…

空间自回归模型及 Stata 具体操作步骤

目录 一、理论原理 二、数据准备 三、程序代码及解释 四、代码运行结果 一、理论原理 空间自回归模型&#xff08;Spatial Autoregressive Model&#xff0c;SAR&#xff09;是一种用于分析具有空间相关性的数据的统计模型。它假设观测值之间的相关性不仅取决于传统的时间或…

xxl-job从2.3.0升级到2.4.1版本遇到的问题及解决方法

一、maven升级版本 <!-- xxl-job包 --> <dependency><groupId>com.xuxueli</groupId><artifactId>xxl-job-core</artifactId><version>2.4.1</version> </dependency> 二、在nacos对应服务的配置文件增加accessToken配…

精益创业方法论在创业实践中的应用:以乔布斯视角探索创新与变革的艺术——张驰咨询

史蒂夫乔布斯以其非凡的愿景、不懈的迭代精神与对产品极致的追求&#xff0c;成为无数创业者心中的灯塔。本文将借鉴乔布斯的创新思维与精益创业方法论相结合&#xff0c;构建一套融合理论与实践的深度框架&#xff0c;旨在指导创业者在不确定的市场环境中高效探索、快速验证并…

用C# 代码调整16位整数大小端的4种方法

四种方法: short BLC(short s) {byte high (byte)((s - s % 256) / 256); //数字减去 低8位, 得到的数字再除以256得到高8位byte low (byte)(s % 256); //数字对256取余数, 得到低8位byte[] change1 { high, low };return BitConverter.ToInt16(change1); }short BLC2(sh…

使用ffmpeg将一个目录下的mkv格式的视频文件转换成mp4格式

最近学剪辑&#xff0c;从BT种子下载的素材资源都是mkv格式的&#xff0c;不能直接导入到视频剪辑软件中。这种情况下需要用一些格式转换工具进行转换&#xff0c;也可以使用ffmpeg进行编辑。 ffmpeg是一个命令行工具&#xff0c;用来对本地的音频视频软件进行编辑。ffmpeg我也…

【动态规划】回文串问题

一、经验总结 对于回文串问题&#xff0c;传统的以i位置为结尾的状态表示已经不能满足要求&#xff0c;无法推导状态转移方程。应该创建一个二维dp表&#xff0c;将所有子串[i, j]的状态表示出来二维dp表的初始化和填表顺序略微复杂&#xff0c;有时需要借助网格图像分析 二、…

Web安全:SQL注入

一、SQL注入三要素 1、用户可以对输入的参数值进行修改。 2、后端不对用户输入的参数值进行严格过滤。 3、用户修改后的参数值可以被带入后端中成功执行&#xff0c;并返回一定结果。 二、SQL注入原理 简单来说&#xff0c;用户输入的值会被插入到SQL语句中&#xff0c;然后…

秋招突击——7/10——复习{}——新作{在排序数组中查找元素的第一个最后一个位置、搜索旋转排序数组}

文章目录 引言复习新作在排序数组中查找元素的第一个和最后一个位置个人实现参考实现 搜索旋转排序数组个人实现参考实现 总结 引言 复习 新作 在排序数组中查找元素的第一个和最后一个位置 题目链接 注意 非递减序列》元素是递增或者相等&#xff0c;并不是严格递增的找到…

什么软件可以AI生成PPT?交给这5款AI PPT工具就完事

话说在当下快节奏的工作中&#xff0c;PPT制作几乎已经成为不可或缺的一部分~每天不是在做PPT的路上&#xff0c;就是在改PPT的途中。 好在幸运的是&#xff0c;现在可有不少好用的AI PPT制作工具能够来帮助我们轻松应对这一难题&#xff01;今天就来给大家分享5款实在又百搭的…

Autosar网络管理:发出第一帧网络管理报文的方法

Autosar网络管理:发出第一帧网络管理报文的方法 1. 为什么要第一帧发出网络管理报文 很多OEM要求CAN网络管理第一帧发出的是网络管理报文,目的是为了快速唤醒CAN网络 2. 节点外发第一帧报文不是网络管理报文的原因 首先根据AUTOSAR CANNM规范要求,节点要能够发出网络管理…

TCP协议双向网络通讯---Python实现

本篇文章是博主在人工智能、网络通讯等领域学习时&#xff0c;用于个人学习、研究或者欣赏使用&#xff0c;并基于博主对人工智能等领域的一些理解而记录的学习摘录和笔记&#xff0c;若有不当和侵权之处&#xff0c;指出后将会立即改正&#xff0c;还望谅解。文章分类在Python…

捷配笔记-PCB阻焊颜色对产品有什么影响?

阻焊层也称为阻焊层或阻焊剂。它是一种薄的聚合物层&#xff0c;应用于&#xff08;PCB&#xff09;。阻焊层的目的是保护PCB表面&#xff0c;并有助于防止焊桥。焊桥是两个导体之间的无意连接&#xff0c;通常是由于存在一小块焊料。需要注意的是&#xff0c;阻焊层被视为其单…

electron实现右键菜单保存图片功能

1.创建窗口&#xff0c;加载页面&#xff0c;代码如下&#xff1a; //打开窗口const {ipcMain, BrowserWindow} require("electron") const saveImage require("../ipcMain/saveImage") let win null; ipcMain.handle(on-open-event, (event, args) &g…