当前位置: 首页 > news >正文

排序算法之计数排序详细解读(附带Java代码解读)

计数排序(Counting Sort)是一种非比较型的排序算法,它通过统计每个元素的出现频率,然后计算元素的位置信息,最后将元素放到正确的位置,从而实现排序。计数排序特别适用于元素范围有限的情况,比如整数的范围较小。

算法思想

计数排序的基本思想是:

  1. 确定范围:找出待排序数据的最小值和最大值。
  2. 计数:创建一个计数数组,用来统计每个元素出现的次数。
  3. 累积:将计数数组中的计数值累积,以确定每个元素的最终位置。
  4. 排序:根据累积的计数信息将元素放到正确的位置。

过程示例

假设有一个待排序的数组:[4, 2, 2, 8, 3, 3, 1]

步骤 1: 确定范围

  1. 找到最小值和最大值:
    • 最小值 = 1
    • 最大值 = 8

步骤 2: 计数

  1. 创建一个计数数组 count,大小为 最大值 - 最小值 + 1

    • count 数组大小为 8(从 1 到 8)。
    • 初始化 count 数组为全零:count = [0, 0, 0, 0, 0, 0, 0, 0]
  2. 统计每个元素出现的次数:

    • 4 → count[4 - 1] += 1count = [0, 0, 0, 1, 0, 0, 0, 0]
    • 2 → count[2 - 1] += 1count = [0, 1, 0, 1, 0, 0, 0, 0]
    • 2 → count[2 - 1] += 1count = [0, 2, 0, 1, 0, 0, 0, 0]
    • 8 → count[8 - 1] += 1count = [0, 2, 0, 1, 0, 0, 0, 1]
    • 3 → count[3 - 1] += 1count = [0, 2, 1, 1, 0, 0, 0, 1]
    • 3 → count[3 - 1] += 1count = [0, 2, 2, 1, 0, 0, 0, 1]
    • 1 → count[1 - 1] += 1count = [1, 2, 2, 1, 0, 0, 0, 1]

步骤 3: 累积

  1. count 数组进行累积:

    • count = [1, 3, 5, 6, 6, 6, 6, 7]
  2. 累积过程:

    • 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: 排序

  1. 创建一个输出数组 output,用于存放排序后的结果:

    • output = [0, 0, 0, 0, 0, 0, 0, 0]
  2. 从原数组中取出元素,并根据 count 数组确定其位置:

    • 4 → output[count[4 - 1] - 1] = 4count[4 - 1] -= 1output = [0, 0, 0, 4, 0, 0, 0, 0]
    • 2 → output[count[2 - 1] - 1] = 2count[2 - 1] -= 1output = [0, 0, 2, 4, 0, 0, 0, 0]
    • 2 → output[count[2 - 1] - 1] = 2count[2 - 1] -= 1output = [0, 2, 2, 4, 0, 0, 0, 0]
    • 8 → output[count[8 - 1] - 1] = 8count[8 - 1] -= 1output = [0, 2, 2, 4, 0, 0, 0, 8]
    • 3 → output[count[3 - 1] - 1] = 3count[3 - 1] -= 1output = [0, 2, 2, 3, 0, 0, 0, 8]
    • 3 → output[count[3 - 1] - 1] = 3count[3 - 1] -= 1output = [0, 2, 2, 3, 3, 0, 0, 8]
    • 1 → output[count[1 - 1] - 1] = 1count[1 - 1] -= 1output = [1, 2, 2, 3, 3, 0, 0, 8]

    最终 output 数组为:[1, 2, 2, 3, 3, 4, 8]

算法复杂度

  • 时间复杂度:

    • 最坏情况: O(n + k)
    • 平均情况: O(n + k)
    • 最佳情况: O(n + k)

    其中,n 是元素的数量,k 是元素的范围(最大值 - 最小值 + 1)。

  • 空间复杂度: O(n + k) 需要额外的空间来存储计数数组和输出数组。

优点

  1. 稳定排序:计数排序是一种稳定的排序算法,即相同元素的相对顺序不会改变。
  2. 时间复杂度低:在元素范围有限的情况下,时间复杂度接近线性。

缺点

  1. 空间复杂度高:需要额外的空间来存储计数数组,特别是当元素的范围很大时。
  2. 不适用大范围数据:当数据范围远大于元素数量时,计数排序的空间复杂度可能变得不可接受。

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 + " ");}}
}

代码说明

  1. countingSort方法:

    • countingSort 方法首先找到数组的最小值和最大值,然后创建计数数组和输出数组。
    • 统计每个元素的出现次数,并将计数数组进行累积。
    • 根据累积的计数信息将元素放到正确的位置,并将排序结果复制回原数组。
  2. 找最小值和最大值:

    • 确定数据的范围,以便创建适当大小的计数数组。
  3. 计数每个元素:

    • 使用计数数组统计每个元素的出现次数。
  4. 累积计数数组:

    • 将计数数组累积,以确定每个元素的最终位置。
  5. 排序到输出数组:

    • 根据累积计数信息将元素放到正确的位置,并将排序结果复制回原数组。

 

 

相关文章:

排序算法之计数排序详细解读(附带Java代码解读)

计数排序&#xff08;Counting Sort&#xff09;是一种非比较型的排序算法&#xff0c;它通过统计每个元素的出现频率&#xff0c;然后计算元素的位置信息&#xff0c;最后将元素放到正确的位置&#xff0c;从而实现排序。计数排序特别适用于元素范围有限的情况&#xff0c;比如…...

Linux:如何使用 Crontab

今天想了解一下Linux Crontab。嗯&#xff0c;在Windows上&#xff0c;可以看做和定时任务差不多。 “要在特定时间进行特定工作。” 如果是这样&#xff0c;可以使用crontab&#xff0c;轻松使用Linux。 1. 基本 (crontab basic) 先看一下基本的crontab使用方法吧。在Linu…...

AI模型:追求全能还是专精?-- 之7 智能工厂程序设计

Q1、感觉上上面离我想做的事情却来越远了。我们跳过讨论直接进入程序设计吧。StringProcessor&#xff08;文字/信息/数字&#xff09;抽象代理工厂-创造 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. 前言 本文主要为大家介绍&#xff0c;如何使用两个简单软件…...

学习记录:js算法(二十五):合并两个有序链表

文章目录 合并两个有序链表我的思路网上思路 总结 合并两个有序链表 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 图一 示例 1&#xff1a;&#xff08;如图一&#xff09; 输入&#xff1a;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 &#xff5e; n 整数中 1 …...

K8S - 理解volumeMounts 中的subpath

在上一篇文章中 springboot service如何动态读取外部配置文件 介绍了springboot 中如何实时读取外部配置文件的内容 部署在K8S 接下来我把它部署在k8s 首先&#xff0c; 我们把配置文件放入项目某个目录 这步部是必须的&#xff0c; 毕竟我们要引入是项目外部的文件&#xf…...

java工程师成功转型大数据

时间&#xff1a;2024年09月06日 作者&#xff1a;小蒋聊技术 邮箱&#xff1a;wei_wei10163.com 微信&#xff1a;wei_wei10 音频&#xff1a;喜马拉雅 希望大家帮个忙&#xff01;如果大家有工作机会&#xff0c;希望帮小蒋推荐一下&#xff0c;小蒋希望遇到一个认真做事…...

visual studio 2022更新以后,之前的有些工程编译出错,升级到Visual studio Enterprise 2022 Preview解决

系列文章目录 文章目录 系列文章目录前言一、解决方法 前言 今天遇到一个问题&#xff1a;visual studio 2022升级成预览版以后&#xff0c;之前的有些工程编译出错。首先代码、项目设置都没有改变&#xff0c;只是更新了visual studio 2022。 在编译工程时&#xff0c;编译器…...

Linux 性能调优技巧

1理解 Linux 性能的基本组成 CPU 使用率&#xff1a;衡量 CPU 在单位时间内被占用的程度。内存使用&#xff1a;关注的是活跃内存与缓存内存的比例&#xff0c;以及是否有过多的交换。I/O 性能&#xff1a;磁盘读写速度直接影响应用程序的响应时间和吞吐量。网络性能&#xff…...

【网络安全】WordPress Uncontrolled Resource Consumption

未经许可,不得转载。 文章目录 WordPresswp-cron.php实战漏洞危害解决措施WordPress WordPress 是全球最广泛使用的内容管理系统(CMS),目前约有 43% 的网站依赖于它。由于其用户友好的界面和丰富的插件功能,WordPress 成为了全球最受欢迎的 CMS。 然而,在使用 WordPres…...

gitee绑定公钥后依旧无法使用_gitee push添加公钥无效

解决&#xff1a; 步骤按照官网操作即可&#xff1a;gitee官方说明 看看远程地址是否使用的http模式&#xff0c;是的话换ssh模式...

Linux 删除 当前下的 mysql-8.0.31 空文件夹

在Linux中&#xff0c;如果你想要删除当前目录下的名为mysql-8.0.31的空文件夹&#xff08;即该文件夹内没有任何文件或子文件夹&#xff09;&#xff0c;你可以使用rmdir命令。但是&#xff0c;如果mysql-8.0.31文件夹并非完全为空&#xff08;即它包含文件或子文件夹&#xf…...

2024,中国服务器操作系统迎云智主升浪

“主升浪”描述了股市中一轮行情中涨幅最大、上升持续时间最长的阶段。2024年&#xff0c;云与AI深度融合形成了数字经济主升浪&#xff0c;从而打开了中国服务器操作系统的黄金机遇期。 2024年注定将成为非常不平凡的一年。不仅是实现“十四五”规划目标任务的关键一年&#x…...

STM32快速复习(九)RTC时钟模块

文章目录 前言一、RTC是什么&#xff1f;RTC的工作原理&#xff1f;二、库函数以及示例1.标准库函数2.示例代码 总结 前言 STM32 的实时时钟&#xff08;RTC&#xff09;是一个独立的定时器。 STM32 的 RTC 模块拥有一组连续计数的计数器&#xff0c;在相应软件配置下&#xf…...

Nacos注册中心与OpenFeign远程调用

文章目录 一、注册中心原理二、Nacos注册中心三、服务注册四、服务发现五、OpenFeign 一、注册中心原理 在微服务当中必须有两个角色 服务提供者&#xff1a;提供接口供其它微服务访问 服务消费者&#xff1a;调用其它微服务提供的接口 在大型微服务项目中&#xff0c;服务提供…...

【基础算法总结】双指针

目录 一&#xff0c;双指针算法介绍二&#xff0c;算法原理和代码实现283.移动零1089.复写零202.快乐数11.盛最多水的容器611.有效三角形的个数LRC179.和为s的两个数15.三数之和18.四数之和 三&#xff0c;算法总结 一&#xff0c;双指针算法介绍 双指针算法是基础算法之一&am…...

教你制作一本一对一授权才能阅读的样本册

在这个信息时代&#xff0c;保护个人隐私变得越来越重要。一对一授权阅读机制&#xff0c;正是为了满足这一需求而诞生。今天&#xff0c;就让我来教你如何制作一本只有一对一授权才能阅读的样本册。这不仅适用于保护个人隐私&#xff0c;还能为企业、研究机构等提供安全、高效…...

【DEV工具-IDEA】idea的光标变成黑块了?

项目场景&#xff1a; 解决&#xff1a;windows&#xff1a;按一下insert键。...

没通过算法备案 或许是这几点你没做好

没通过算法备案 或许是这几点你没做好 当企业提交算法备案遭遇“不予通过”时&#xff0c;往往是因为一些看似微小却至关重要的细节未能达到标准。以下是一些常见的原因&#xff0c;希望能为准备备案的企业提供一些预警和指导&#xff1a; ICP备案缺失&#xff1a;互联网信息服…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成

厌倦手动写WordPress文章&#xff1f;AI自动生成&#xff0c;效率提升10倍&#xff01; 支持多语言、自动配图、定时发布&#xff0c;让内容创作更轻松&#xff01; AI内容生成 → 不想每天写文章&#xff1f;AI一键生成高质量内容&#xff01;多语言支持 → 跨境电商必备&am…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述&#xff1a;海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而&#xff0c;目前该领域仍面临一个挑战&#xff0c;即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)

一、OpenBCI_GUI 项目概述 &#xff08;一&#xff09;项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台&#xff0c;其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言&#xff0c;首次接触 OpenBCI 设备时&#xff0c;往…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...

华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)

题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...

一些实用的chrome扩展0x01

简介 浏览器扩展程序有助于自动化任务、查找隐藏的漏洞、隐藏自身痕迹。以下列出了一些必备扩展程序&#xff0c;无论是测试应用程序、搜寻漏洞还是收集情报&#xff0c;它们都能提升工作流程。 FoxyProxy 代理管理工具&#xff0c;此扩展简化了使用代理&#xff08;如 Burp…...