(十八)排序算法-计数排序

news2024/9/20 12:40:31

1 基本介绍

1.1 概述

计数排序是一个非基于比较的排序算法,元素从未排序状态变为已排序状态的过程,是由额外空间的辅助和元素本身的值决定的。该算法于1954年由 Harold H. Seward 提出。它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围),快于任何比较排序算法。这是一种牺牲空间换取时间的做法。

排序步骤:

  1. 找出待排序的数组中最大和最小的元素;
  2. 统计数组中每个值为i的元素出现的次数,存入数组C的第i项;
  3. 对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加);
  4. 反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1

1.2 算法详解

下面通过图解的方式了解计数排序的思想。

  1. 第一次遍历序列,找出序列中的最大值以及最小值,然后根据最大值MAX与最小值MIN创建一个MAX-MIN+1长度的数组。为什么创建这样长度的数组呢?因为只有创建了这样长度的数组,MIN-MAX区间内的每个元素才有对应的位置进行存放,如下图所示。

在这里插入图片描述

  1. 第二次遍历序列,每次遍历一个元素都将该元素所对应的区间数组对应的位置进行+1操作,这个步骤其实就是计数排序的核心----计数。遍历结束之后,区间数组中的元素值就代表相应元素出现的次数,如下图所示。

在这里插入图片描述

  1. 最后一步就只需要按照区间数组中的次数一次将该元素打印出来即可。如下图所示。
    在这里插入图片描述

了解完计数排序的基本思想之后,分析一下计数排序算法的一些特点:

  • 计数排序是稳定的 ,这个大家应该能很明显的看出来,因为计数排序本身并不是基于比较的算法。
  • 计数排序需要的额外空间比较大,这个大家很明显的看出来,并且空间浪费的情况也会比较严重,因为一旦序列中MAX与MIN的差距过大,那么需要的内存空间就会非常大。并且假如序列中的元素都是散布在一个特定的区间内,那么内存空间浪费的情况也会非常明显。

算法图解:
在这里插入图片描述

2 代码实现

/**
 * 计数排序
 */
public class CountSort {
    public static void main(String[] args) {
        int []num ={7,4,9,3,2,1,8,6,5,10};
        long startTime=System.currentTimeMillis();
        int min=Integer.MAX_VALUE;
        int max=Integer.MIN_VALUE;
        //先找出数组中的最大值与最小值
        for(int i=0;i<num.length;i++) {
            if(num[i]<min)
                min=num[i];
            if(num[i]>max)
                max=num[i];
        }
        //创建一个长度为max-min+1长度的数组来进行计数
        int []figure=new int [max-min+1];
        for(int i=0;i<num.length;i++) {
            //计算每个数据出现的次数
            figure[num[i]-min]++;
        }
        int begin=0;
        //创建一个新的数组来存储已经排序完成的结果
        int []num1=new int [num.length];
        for(int i=0;i<figure.length;i++) {
            //循环将数据pop出来
            if(figure[i]!=0) {
                for(int j=0;j<figure[i];j++) {
                    num1[begin++]=min+i;
                }
            }
        }
        System.out.println("数据范围:"+min+"~"+max);
        System.out.println("计数结果:  ");
        for(int i=0;i<num.length;i++)
            System.out.println("         "+num[i]+"出现"+figure[num[i]-min]+"次");
        System.out.print("排序结果:  ");
        for(int i=0;i<num1.length;i++)
            System.out.print(num1[i]+"   ");
        System.out.println();
        long endTime=System.currentTimeMillis();
        System.out.println("程序运行时间: "+(endTime-startTime)+"ms");
    }

}

3 复杂度分析

  • 时间复杂度
    计数排序很明显是一种通过空间来换时间的算法,因为我们可以很明显的看到计数排序需要三次遍历,两次遍历我们的原序列,第三次是遍历我们的区间数组.那么很明显时间复杂度一定是线性级别的但是因为第三次遍历的并不是我们的原序列,而是我们的区间数组,所以时间复杂度并不是我们的平常的O(n),而是应该加上我们遍历区间数组的时间,假设我们的区间数组长度为k的话,那么我们的时间复杂度就是O(n+k)

  • 空间复杂度
    上面我们已经说过了,计数排序本身就是一个通过空间来换取时间的算法,所以很明显他的空间复杂度就会很高.并且这个空间复杂度主要就取决于我们区间数组的长度,所以假设我们的区间数组长度为k的话,那么我们的空间复杂度就为O(k)

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

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

相关文章

一文解读基于PaddleSeg的钢筋长度超限监控方案

项目背景 钢铁厂生产钢筋的过程中会存在部分钢筋长度超限的问题&#xff0c;如果不进行处理&#xff0c;容易造成机械臂损伤。因此&#xff0c;需要通过质检流程&#xff0c;筛选出存在长度超限问题的钢筋批次&#xff0c;并进行预警。传统的处理方式是人工核查&#xff0c;该方…

数组(九)-- LC[316][321][402] 去除重复字母

1 移掉 K 位数字 1.1 题目描述 题目链接&#xff1a;https://leetcode.cn/problems/remove-k-digits/ 1.2 思路分析 这道题让我们从一个字符串数字中删除 k 个数字&#xff0c;使得剩下的数最小。也就说&#xff0c;我们要保持原来的数字的相对位置不变。 以题目中的 num1432…

深度学习第J5周:DenseNet+SE-Net实战

目录 一、介绍 二、前期准备 二、模型 三、训练运行 3.1训练 3.2指定图片进行预测 &#x1f368; 本文为[&#x1f517;365天深度学习训练营]内部限免文章&#xff08;版权归 *K同学啊* 所有&#xff09; &#x1f356; 作者&#xff1a;[K同学啊] &#x1f4cc; 本周任务&…

网络安全之防火墙

目录 网络安全之防火墙 路由交换终归结底是联通新设备 防御对象&#xff1a; 定义&#xff1a; 防火墙的区域划分&#xff1a; 包过滤防火墙 --- 访问控制列表技术 --- 三层技术 代理防火墙 --- 中间人技术 --- 应用层 状态防火墙 --- 会话追踪技术 --- 三层、四层 UTM…

【手把手带你五分钟手机端注册使用GPT的强力对手Claude,免费,无任何成本】

前言 今天刷到了号称是媲美GPT-4的Claude介绍&#xff0c;无需魔法&#xff0c;无任何成本即可以使用&#xff0c;果断尝试注册使用&#xff0c;效果确实不错&#xff0c;关键是免费无成本&#xff01;&#xff01;&#xff01; Claude使用的是Constitutional AI模型。ChatGPT…

亚马逊平台快速消耗滞销品的七大方式

一、亚马逊后台直接进行清仓 1、卖家和商品的资格 在管理多余库存页面上&#xff0c;可以查看亚马逊根据买家需求和其他因素推荐了哪些符合要求的商品参加清仓计划。商品当前价格下的消息将显示商品是否符合清仓促销要求(通过创建清仓促销提交)或清仓店铺要求(通过创建销售提…

Windos下设置java项目开机自启动

这里是将java项目注册为Windows服务实现开机自启动。 查看.NET framework版本 因为使用winsw工具运行时需要使用.NET framework,基本上现在的win10系统带自带有.NET framework4.0&#xff0c;为了选择合适的版本&#xff0c;我们可以查看本机.NET Framework版本&#xff0c;根…

差速巡线机器人设计-良好(80+)的报告-2023

如何提分&#xff1f;将一篇报告提升20分以上呢&#xff1f;差速巡线机器人设计-及格&#xff08;60&#xff09;的报告-2023_zhangrelay的博客-CSDN博客姓名&#xff1a; 学号&#xff1a; 实践项目1名称&#xff1a;差速巡线机器人设计 60分&#xff1a;缺乏思考、没有对比、…

恒生电子面试题总结

CPU突然飙升&#xff0c;如何排查 1.监控cpu运行状态&#xff0c;显示进程运行信息列表 top -c 2. 按CPU使用率排序&#xff0c;键入大写的P P 3.用 top -Hp 命令查看占用 CPU 最高的线程 上一步用 top命令找到了那个 Java 进程。那一个进程中有那么多线程&#xff0c;不可…

[oeasy]python0132_[趣味拓展]emoji_表情符号_抽象话_由来_流汗黄豆

emoji表情符号 回忆上次内容 上次了解了unicode 和 utf-8 unicode是字符集utf-8是一种可变长度的编码方式utf-8是实现unicode的存储和传输的现实的方式 "拜"字 unicode编码是0x62dcutf-8字节形式是b"\xe6\x8b\x9c" 如果我想看看 b"\x62\xdc"用…

准确率、精确率、召回率、F1score和混淆矩阵

准确率和PR、confusion matrix的概念初次接触是在六年前&#xff0c;2017着手在做激光雷达点云处理的相关事宜&#xff0c;六年时光不长&#xff0c;却有很多事情发生。 精确率 precision 也叫查准率&#xff0c;即正确预测为正的占全部预测为正的比例(不准错&#xff0c;宁愿…

图解redis发布和订阅

目录 1.什么是发布订阅 1.1概念 1.2发布订阅过程 1.3发布订阅分为两类 2. 频道的订阅与退订 2.1subcribe 2.2退订频道 3. 模式的订阅和退订 3.1模式的订阅 3.2punsubscribe 4.频道和模式的发布 4.1频道的发布 4.2模式的发布 1.什么是发布订阅 1.1概念 1.发布订阅…

【电源专题】案例:充电芯片如何配置NTC偏置网络设定充电温度区间

背景 充电芯片是需要检测电池内部的NTC电阻来得到电池此时的温度,然后根据温度来判断自己是否要进行充电。因此在导入充电芯片过程中,我们需要设置NTC的偏置网络来设定能充电的温度范围。如下图所示为SGM41523芯片的典型应用图: RT1和RT2为NTC的偏置网络。 在规格书的更详细…

【U8+】修改用友U8+填制凭证界面字体大小

【问题描述】 在使用用友U8软件填制凭证功能时&#xff0c; 觉得【填制凭证】界面字体太小&#xff0c;看着不方便。 想要进行调整。 【解决方法】 1、打开填制凭证界面&#xff0c; 点击最上方【选项】按钮&#xff1b; 2、在弹出的凭证选项设置窗口中&#xff0c; 找到【凭…

PHP语言请求示例,电商商品详情接口(item_get-根据ID取商品详情)代码封装教程

item_get-根据ID取商品详情接口 通过代码封装该接口可以拿到商品标题&#xff0c;商品价格&#xff0c;商品促销信息&#xff0c;商品优惠价&#xff0c;商品库存&#xff0c;sku属性&#xff0c;商品图片&#xff0c;desc图片&#xff0c;desc描述&#xff0c;sku图片&#xf…

抓包工具Wireshark安装与使用

windows下安装 下载安装包 Npcap wireshark依赖于Npcap或者Winpcap软件捕获网络实时数据。这里选择Npcap。下载地址&#xff1a;https://npcap.com/#download。Wireshark Wireshark是一个开源的网络数据包分析器。该分析器尽可能详细地展示捕获的包数据。下载地址&#xff1a…

C++ 数组、指针、数组指针、指针数组、多级指针、STL-map、结构体 的 初始化 及其 初始化赋值

C 数组、指针、数组指针、指针数组、多级指针、STL-map、结构体 的 初始化 及其 初始化赋值C 数组、指针、数组指针、指针数组、多级指针、STL-map、结构体 的 初始化 及其 初始化赋值C 数组、指针、数组指针、指针数组、多级指针数组一维数组初始化&#xff1a;二维数组初始化…

8.1 假设验证的基本概念

学习目标&#xff1a; 要学习假设检验的基本概念&#xff0c;我会按照以下步骤进行&#xff1a; 了解假设检验的基本概念&#xff1a;假设检验是一种统计推断方法&#xff0c;用于判断某个假设是否成立。一般来说&#xff0c;假设检验包括原假设和备择假设两个假设&#xff0c…

语雀笔记备份导出

参考: https://www.cnblogs.com/ssslinppp/p/17020303.htmlhttps://github.com/yuque/yuque-exporterhttps://zhuanlan.zhihu.com/p/582287220https://www.yuque.com/duzh929/blog/ocffqghttps://www.yuque.com/hijiaobu/datalife/onf6sy#BKajf 现在需要超级管理员,若是没有超级…

JDK8新特性 (Lambda表达式和Stream流式编程)

目录 一&#xff1a;JDK8新特性 1. Java SE的发展历史 2. 了解Open JDK 和 Oracle JDK 3. JDK 8新特性 3.1 Lambda表达式&#xff08;重点&#xff09; 3.2 接口的增强 3.3 函数式接口 3.4 方法引用 3.5 集合之Stream流式操作&#xff08;重点&#xff09; 3.6 新的时…