排序算法之计数排序详细解读(附带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备案缺失:互联网信息服…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...
