排序算法之计数排序详细解读(附带Java代码解读)
计数排序(Counting Sort)是一种非比较型的排序算法,它通过统计每个元素的出现频率,然后计算元素的位置信息,最后将元素放到正确的位置,从而实现排序。计数排序特别适用于元素范围有限的情况,比如整数的范围较小。
算法思想
计数排序的基本思想是:
- 确定范围:找出待排序数据的最小值和最大值。
- 计数:创建一个计数数组,用来统计每个元素出现的次数。
- 累积:将计数数组中的计数值累积,以确定每个元素的最终位置。
- 排序:根据累积的计数信息将元素放到正确的位置。
过程示例
假设有一个待排序的数组:[4, 2, 2, 8, 3, 3, 1]
步骤 1: 确定范围
- 找到最小值和最大值:
- 最小值 = 1
- 最大值 = 8
步骤 2: 计数
-
创建一个计数数组
count,大小为最大值 - 最小值 + 1:count数组大小为 8(从 1 到 8)。- 初始化
count数组为全零:count = [0, 0, 0, 0, 0, 0, 0, 0]。
-
统计每个元素出现的次数:
- 4 →
count[4 - 1] += 1,count = [0, 0, 0, 1, 0, 0, 0, 0] - 2 →
count[2 - 1] += 1,count = [0, 1, 0, 1, 0, 0, 0, 0] - 2 →
count[2 - 1] += 1,count = [0, 2, 0, 1, 0, 0, 0, 0] - 8 →
count[8 - 1] += 1,count = [0, 2, 0, 1, 0, 0, 0, 1] - 3 →
count[3 - 1] += 1,count = [0, 2, 1, 1, 0, 0, 0, 1] - 3 →
count[3 - 1] += 1,count = [0, 2, 2, 1, 0, 0, 0, 1] - 1 →
count[1 - 1] += 1,count = [1, 2, 2, 1, 0, 0, 0, 1]
- 4 →
步骤 3: 累积
-
将
count数组进行累积:count = [1, 3, 5, 6, 6, 6, 6, 7]
-
累积过程:
count[1] += count[0],count = [1, 3, 2, 1, 0, 0, 0, 1]count[2] += count[1],count = [1, 3, 5, 1, 0, 0, 0, 1]count[3] += count[2],count = [1, 3, 5, 6, 0, 0, 0, 1]count[4] += count[3],count = [1, 3, 5, 6, 6, 0, 0, 1]count[5] += count[4],count = [1, 3, 5, 6, 6, 6, 0, 1]count[6] += count[5],count = [1, 3, 5, 6, 6, 6, 6, 1]count[7] += count[6],count = [1, 3, 5, 6, 6, 6, 6, 7]
步骤 4: 排序
-
创建一个输出数组
output,用于存放排序后的结果:output = [0, 0, 0, 0, 0, 0, 0, 0]
-
从原数组中取出元素,并根据
count数组确定其位置:- 4 →
output[count[4 - 1] - 1] = 4,count[4 - 1] -= 1,output = [0, 0, 0, 4, 0, 0, 0, 0] - 2 →
output[count[2 - 1] - 1] = 2,count[2 - 1] -= 1,output = [0, 0, 2, 4, 0, 0, 0, 0] - 2 →
output[count[2 - 1] - 1] = 2,count[2 - 1] -= 1,output = [0, 2, 2, 4, 0, 0, 0, 0] - 8 →
output[count[8 - 1] - 1] = 8,count[8 - 1] -= 1,output = [0, 2, 2, 4, 0, 0, 0, 8] - 3 →
output[count[3 - 1] - 1] = 3,count[3 - 1] -= 1,output = [0, 2, 2, 3, 0, 0, 0, 8] - 3 →
output[count[3 - 1] - 1] = 3,count[3 - 1] -= 1,output = [0, 2, 2, 3, 3, 0, 0, 8] - 1 →
output[count[1 - 1] - 1] = 1,count[1 - 1] -= 1,output = [1, 2, 2, 3, 3, 0, 0, 8]
最终
output数组为:[1, 2, 2, 3, 3, 4, 8] - 4 →
算法复杂度
-
时间复杂度:
- 最坏情况: O(n + k)
- 平均情况: O(n + k)
- 最佳情况: O(n + k)
其中,n 是元素的数量,k 是元素的范围(最大值 - 最小值 + 1)。
-
空间复杂度: O(n + k) 需要额外的空间来存储计数数组和输出数组。
优点
- 稳定排序:计数排序是一种稳定的排序算法,即相同元素的相对顺序不会改变。
- 时间复杂度低:在元素范围有限的情况下,时间复杂度接近线性。
缺点
- 空间复杂度高:需要额外的空间来存储计数数组,特别是当元素的范围很大时。
- 不适用大范围数据:当数据范围远大于元素数量时,计数排序的空间复杂度可能变得不可接受。
Java代码解读
public class CountingSort {// 主方法:执行计数排序public static void countingSort(int[] arr) {if (arr.length == 0) return;// 1. 找到最小值和最大值int min = arr[0];int max = arr[0];for (int num : arr) {if (num < min) min = num;if (num > max) max = num;}// 2. 创建计数数组int range = max - min + 1;int[] count = new int[range];int[] output = new int[arr.length];// 3. 计数每个元素的出现次数for (int num : arr) {count[num - min]++;}// 4. 累积计数数组for (int i = 1; i < range; i++) {count[i] += count[i - 1];}// 5. 排序元素到输出数组for (int i = arr.length - 1; i >= 0; i--) {output[count[arr[i] - min] - 1] = arr[i];count[arr[i] - min]--;}// 6. 将排序结果复制回原数组System.arraycopy(output, 0, arr, 0, arr.length);}public static void main(String[] args) {int[] arr = {4, 2, 2, 8, 3, 3, 1};System.out.println("排序前的数组:");for (int num : arr) {System.out.print(num + " ");}System.out.println();countingSort(arr);System.out.println("排序后的数组:");for (int num : arr) {System.out.print(num + " ");}}
}
代码说明
-
countingSort方法:
countingSort方法首先找到数组的最小值和最大值,然后创建计数数组和输出数组。- 统计每个元素的出现次数,并将计数数组进行累积。
- 根据累积的计数信息将元素放到正确的位置,并将排序结果复制回原数组。
-
找最小值和最大值:
- 确定数据的范围,以便创建适当大小的计数数组。
-
计数每个元素:
- 使用计数数组统计每个元素的出现次数。
-
累积计数数组:
- 将计数数组累积,以确定每个元素的最终位置。
-
排序到输出数组:
- 根据累积计数信息将元素放到正确的位置,并将排序结果复制回原数组。
相关文章:
排序算法之计数排序详细解读(附带Java代码解读)
计数排序(Counting Sort)是一种非比较型的排序算法,它通过统计每个元素的出现频率,然后计算元素的位置信息,最后将元素放到正确的位置,从而实现排序。计数排序特别适用于元素范围有限的情况,比如…...
Linux:如何使用 Crontab
今天想了解一下Linux Crontab。嗯,在Windows上,可以看做和定时任务差不多。 “要在特定时间进行特定工作。” 如果是这样,可以使用crontab,轻松使用Linux。 1. 基本 (crontab basic) 先看一下基本的crontab使用方法吧。在Linu…...
AI模型:追求全能还是专精?-- 之7 智能工厂程序设计
Q1、感觉上上面离我想做的事情却来越远了。我们跳过讨论直接进入程序设计吧。StringProcessor(文字/信息/数字)抽象代理工厂-创造 Universal given时空区域 |bar PROCESS: 页面版块的图式schema/概念的KE图式CaseFilter 一般应用工厂-制造- General sign…...
如何在本地服务器部署SeaFile自托管文件共享服务结合内网穿透打造私有云盘?
文章目录 1. 前言2. SeaFile云盘设置2.1 Owncould的安装环境设置2.2 SeaFile下载安装2.3 SeaFile的配置 3. cpolar内网穿透3.1 下载安装3.2 Cpolar注册3.3 Cpolar云端设置3.4 Cpolar本地设置 4.公网访问测试5.结语 1. 前言 本文主要为大家介绍,如何使用两个简单软件…...
学习记录:js算法(二十五):合并两个有序链表
文章目录 合并两个有序链表我的思路网上思路 总结 合并两个有序链表 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 图一 示例 1:(如图一) 输入:l1 [1,2,4], l2 [1,3,4] …...
43. 1 ~ n 整数中 1 出现的次数【难】
comments: true difficulty: 中等 edit_url: https://github.com/doocs/leetcode/edit/main/lcof/%E9%9D%A2%E8%AF%95%E9%A2%9843.%201%EF%BD%9En%E6%95%B4%E6%95%B0%E4%B8%AD1%E5%87%BA%E7%8E%B0%E7%9A%84%E6%AC%A1%E6%95%B0/README.md 面试题 43. 1 ~ n 整数中 1 …...
K8S - 理解volumeMounts 中的subpath
在上一篇文章中 springboot service如何动态读取外部配置文件 介绍了springboot 中如何实时读取外部配置文件的内容 部署在K8S 接下来我把它部署在k8s 首先, 我们把配置文件放入项目某个目录 这步部是必须的, 毕竟我们要引入是项目外部的文件…...
java工程师成功转型大数据
时间:2024年09月06日 作者:小蒋聊技术 邮箱:wei_wei10163.com 微信:wei_wei10 音频:喜马拉雅 希望大家帮个忙!如果大家有工作机会,希望帮小蒋推荐一下,小蒋希望遇到一个认真做事…...
visual studio 2022更新以后,之前的有些工程编译出错,升级到Visual studio Enterprise 2022 Preview解决
系列文章目录 文章目录 系列文章目录前言一、解决方法 前言 今天遇到一个问题:visual studio 2022升级成预览版以后,之前的有些工程编译出错。首先代码、项目设置都没有改变,只是更新了visual studio 2022。 在编译工程时,编译器…...
Linux 性能调优技巧
1理解 Linux 性能的基本组成 CPU 使用率:衡量 CPU 在单位时间内被占用的程度。内存使用:关注的是活跃内存与缓存内存的比例,以及是否有过多的交换。I/O 性能:磁盘读写速度直接影响应用程序的响应时间和吞吐量。网络性能ÿ…...
【网络安全】WordPress Uncontrolled Resource Consumption
未经许可,不得转载。 文章目录 WordPresswp-cron.php实战漏洞危害解决措施WordPress WordPress 是全球最广泛使用的内容管理系统(CMS),目前约有 43% 的网站依赖于它。由于其用户友好的界面和丰富的插件功能,WordPress 成为了全球最受欢迎的 CMS。 然而,在使用 WordPres…...
gitee绑定公钥后依旧无法使用_gitee push添加公钥无效
解决: 步骤按照官网操作即可:gitee官方说明 看看远程地址是否使用的http模式,是的话换ssh模式...
Linux 删除 当前下的 mysql-8.0.31 空文件夹
在Linux中,如果你想要删除当前目录下的名为mysql-8.0.31的空文件夹(即该文件夹内没有任何文件或子文件夹),你可以使用rmdir命令。但是,如果mysql-8.0.31文件夹并非完全为空(即它包含文件或子文件夹…...
2024,中国服务器操作系统迎云智主升浪
“主升浪”描述了股市中一轮行情中涨幅最大、上升持续时间最长的阶段。2024年,云与AI深度融合形成了数字经济主升浪,从而打开了中国服务器操作系统的黄金机遇期。 2024年注定将成为非常不平凡的一年。不仅是实现“十四五”规划目标任务的关键一年&#x…...
STM32快速复习(九)RTC时钟模块
文章目录 前言一、RTC是什么?RTC的工作原理?二、库函数以及示例1.标准库函数2.示例代码 总结 前言 STM32 的实时时钟(RTC)是一个独立的定时器。 STM32 的 RTC 模块拥有一组连续计数的计数器,在相应软件配置下…...
Nacos注册中心与OpenFeign远程调用
文章目录 一、注册中心原理二、Nacos注册中心三、服务注册四、服务发现五、OpenFeign 一、注册中心原理 在微服务当中必须有两个角色 服务提供者:提供接口供其它微服务访问 服务消费者:调用其它微服务提供的接口 在大型微服务项目中,服务提供…...
【基础算法总结】双指针
目录 一,双指针算法介绍二,算法原理和代码实现283.移动零1089.复写零202.快乐数11.盛最多水的容器611.有效三角形的个数LRC179.和为s的两个数15.三数之和18.四数之和 三,算法总结 一,双指针算法介绍 双指针算法是基础算法之一&am…...
教你制作一本一对一授权才能阅读的样本册
在这个信息时代,保护个人隐私变得越来越重要。一对一授权阅读机制,正是为了满足这一需求而诞生。今天,就让我来教你如何制作一本只有一对一授权才能阅读的样本册。这不仅适用于保护个人隐私,还能为企业、研究机构等提供安全、高效…...
【DEV工具-IDEA】idea的光标变成黑块了?
项目场景: 解决:windows:按一下insert键。...
没通过算法备案 或许是这几点你没做好
没通过算法备案 或许是这几点你没做好 当企业提交算法备案遭遇“不予通过”时,往往是因为一些看似微小却至关重要的细节未能达到标准。以下是一些常见的原因,希望能为准备备案的企业提供一些预警和指导: ICP备案缺失:互联网信息服…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
