计数排序 [数据结构与算法][Java]

news2024/11/20 8:41:55

计数排序

计数排序和基数排序都是桶排序的一种应用

适用场景:

量大但是范围小

  • 比如对10000个数进行排序, 但是这10000个数中只有10种数字(0 - 9)
  • 典型题目:
    1. 某大型企业数万名员工年龄排序
    2. 如何快速得知高考名次(腾讯面试)

这里我们以某大型企业数万名员工年龄排序来进行一个讲解:

假设有两万名员工, 员工的年龄在[0 - 60]之间, 那么如何用计数排序完成排序操作?

  1. 首先, 肯定是有一个原始数组, 长度为20万, 其中是放的每个员工的年龄, 我们先对这个原始数组进行一次遍历
  2. 创建一个新的数组(计数数组), 这个数组中对应下标位置放的就是该年龄的人员的数量
    • 例如: 如果是下标为10的位置放的就是10岁的员工的数量
  3. 遍历原数组的过程中, 统计对应年龄的人数(也就是完善计数数组)
  4. 创建一个新的数组(结果数组), 结果数组的长度与原始数组的长度相同
  5. 遍历计数数组, 在遍历的过程中完成在结果数组中值的添加
    • 例如: 计数数组中0有3个, 那么在结果数组中添加3个0, 然后1有4个, 再添加4个1, 一直添加到遍历完技术数组为止

做题理解:

问题:

一个数组中的数值都是0 - 9构成, 现在让你对该数组中数值进行一个升序排序:

算法图解:

在这里插入图片描述

代码:

package com.ffyc.algorithm.计数排序;

import java.util.Arrays;

public class CountSort {
    static int [] sort(int [] arr){
        int [] result = new int[arr.length];
        int [] count = new int[10];

        for(int i = 0; i < arr.length; i++){
            count[arr[i]]++;
        }

        for(int i = 0,j = 0; i < count.length; i++){
            while(count[i]-- > 0) result[j++] = i;
        }

        return result;
    }

    public static void main(String[] args) {
        int [] arr = new int[]{1,1,3,2,5,2,1,3,7,8,6,9};

        int[] sort = sort(arr);

        System.out.println(Arrays.toString(sort));
    }
}

算法优化:

我们可以发现: 基于上面我们设计的计数排序算法, 有一个很大的问题, 那就是这个算法是一个不稳定的排序算法,那么我们要如何解决这一问题? 也就是如何使得我们的计数排序算法成为一个稳定的排序算法?

  • 不稳定 : 排序后元素的相对位置会改变

我们通过一个案例来理解并解决这一不稳定问题

如果这个时候是两万个Employee类(员工类)的对象让你进行排序, 要求使用计数排序算法, 并且排序之后元素的相对位置不变, 那么如何使用计数排序做到?

我们要增加一个累加数组, 我们在原本不稳定的计数排序算法上进行一个如下修改:

  1. 在获取到计数数组之后, 不直接使用计数数组来得到结果数组, 而是使用计数数组求一个累加数组
    • 累加数组中的第i个元素值为: add[i] = count[i] + count[i - 1] + … + count[0];
      • 而我们有了累加数组之后其实原本的计数数组就没有用了, 所以我们直接在原本的计数数组上做一个修改即可:
        • 从前到后遍历一次计数数组, 使得计数数组有性质: count[i] = count[i] + count[i - 1]
  2. 在得到了累加数组之后, 我们可以发现累加数组中的每个元素其实就是对应元素在结果数组中的最后一个位置 + 1
  3. 逆序遍历一次原数组, 在遍历的过程中, 将原数组中的值放在结果数组中合理的位置
    • 什么是合理的位置?
    • 我们下面题目中会使用画图的方式来进行一个解释说明

做题理解:

问题:

一个数组中的数值都是0 - 9构成, 现在让你对该数组中数值进行一个升序排序(要求排序是稳定的):

算法图解:

在这里插入图片描述

代码:

package com.ffyc.algorithm.计数排序;

import java.util.Arrays;

public class CountSort {
    static int [] sortPlus(int [] arr){
        int [] result = new int[arr.length];
        int [] count = new int[10];

        for(int i = 0; i < arr.length; i++){
            count[arr[i]]++;
        }

        for(int i = 1; i < count.length; i++){
            count[i] = count[i] + count[i - 1];
        }

        for(int i = arr.length - 1; i >= 0; i--){
            result[count[arr[i]]-- - 1] = arr[i];
        }

        return result;
    }

    public static void main(String[] args) {
        int [] arr = new int[]{1,1,3,2,5,2,1,3,7,8,6,9};

        int[] sort = sort(arr);

        System.out.println(Arrays.toString(sort));

        int[] sortPlus = sortPlus(arr);

        System.out.println(Arrays.toString(sortPlus));
    }
}

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

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

相关文章

RV1126笔记十四:吸烟行为检测及部署<二>

若该文为原创文章,转载请注明原文出处。 PC下yolov5环境搭建 我使用的训练环境是Windows10+MiniConda 接下来记录搭建全过程 备注:条件允许就使用ubuntu物理机,最好要有显卡,训练有显卡速度会快很多,没有显卡,训练300轮,亲测大概40小时,不值得。 一、miniconda 安装…

从零了解进程(操作系统定位,进程的概念,特征,虚拟地址)

目录 操作系统的定位 进程的概念 如何描述进程? 如何组织进程? 进程的特征 1.pid 2.内存指针 3.文件描述符 4.进程调度的相关属性 (1)进程的状态 (2)优先级 (3)上下文 (4)记账信息 进程是如何利用cpu资源的? 进程的虚拟地址 物理地址 内存随机访问的特性 为…

【ML实验7】人脸识别综合项目(PCA、多分类SVM)

实验代码获取 github repo 山东大学机器学习课程资源索引 实验目的 实验环境 实验内容 PCA 两种方法EVD-PCA和SVD-PCA的实现、效率对比见我之前的博客一个PCA加速技巧&#xff0c;这里补充SVD方法的数学推导&#xff1a; 首先&#xff0c;设方阵AAA的特征值分解为AUΣUTAU\S…

ZKP应用:石头剪刀布游戏

1. 引言 开源代码见&#xff1a; https://github.com/spalladino/zkp-tests 对比了分别使用&#xff1a; Iden3团队的circom语言&#xff08;易于学习ZKP&#xff09;ZCash团队的Halo2框架Aztec团队的Noir语言&#xff08;最友好&#xff09; 编写石头剪刀布游戏的ZKP证明…

IPv6(计算机网络-网络层)

目录 IPv6 的特点 IPv6 数据报的格式 IPv6 分组的格式 IPv6 的扩展首部 从计算机本身发展以及从互联网规模和网络传输速率来看&#xff0c;现在 IPv4已很不适用。 要解决 IP 地址耗尽的问题的措施&#xff1a; 采用无类别编址 CIDR&#xff0c;使 IP 地址的分配更加合理…

MySQL 锁机制

文章目录MySQL 锁机制表锁读锁场景一场景二场景三总结写锁场景一场景二场景三总结行锁场景一场景二总结间隙锁缺点如何锁定一行MySQL 锁机制 表锁 读锁 查看哪些表被加锁了 语法&#xff1a;show open tables 添加读锁 read 读锁关键字 | write 写锁关键字 语法&#xff1a;l…

qt下采用libcurl实现ftp与tftp功能,提供源代码程序

一、FTP简介 FTP&#xff08;文件传输协议&#xff09;&#xff0c;工作在应用层&#xff0c;是用于在网络上进行文件传输的一套标准协议。它使用 TCP 传输&#xff0c;客户在和服务器建立连接前要经过一个“三次握手”的过程&#xff0c; 保证客户与服务器之间的连接是可靠的&…

基于xml的自动装配之byName

基于xml的自动装配之byName 自动装配方式&#xff1a;byName byName&#xff1a;将自动装配的属性的属性名&#xff0c;作为bean的id在IOC容器中匹配相对应的bean进行赋值总结&#xff1a;当类型匹配的 bean 有多个时&#xff0c;此时可以使用 byName 实现自动装配 配置bean &…

02:损失函数总结

目录 nn.L1Loss: nn.NLLLoss: nn.MSELoss: nn.CrossEntropyLoss: 损失函数是用来估量模型的预测值与真实值的不一致程度&#xff0c;它是一个非负实值函数。我们训练模型的过程&#xff0c;就是通过不断的迭代计算&#xff0c;使用梯度下降的优化算法&#xff0c;使得损失函…

多叉树 [数据结构与算法][Java]

多叉树 在二叉树中每个结点只能有一个数据项, 并且最多有两个子节点, 如果允许每个结点可以有更多的数据项和更多的子节点, 那么就是多叉树 多叉树: multiway tree 那么我们为什么要提出多叉树? 因为二叉树有一定的问题: 即使二叉树的操作效率高, 但是也存在问题: 二叉树需…

django之前后端不分离的操作(增删改查)

背景&#xff1a; demo采用的是前后端不分离的操作&#xff0c;用Bootstrap作为前段页面框架使用 1.先说模板之间的继承&#xff08;针对HTML来讲&#xff09; 父模板中编写好公共代码块&#xff0c;例如一个网站的导航和footer部分 在内容部分注明 {%block content%} {%e…

53 记一次自定义 classloader 导致的 metadataspace OOM

前言 这是最近 flink 集群上面暴露出现的一个问题 具体的细节原因 就是 flink 上面提交任务的时候, 自定义的 classloader 加载 driver.jar 然后导致 metaspace OOM 由于这边的 TaskManager metadataspace 配置相对较小(MaxMetaspaceSize配置为96M), 然后导致 出现了 metada…

BUUCTF Misc [SUCTF2018]single dog 我吃三明治 sqltest [SWPU2019]你有没有好好看网课?

[SUCTF2018]single dog 下载文件 使用kali的binwalk工具分析 进行文件分离 解压其中的压缩包&#xff0c;得到1.txt 看内容应该是js加密后的结果&#xff0c;复制到AAEncode在线解密网站 得到flag flag{happy double eleven} 我吃三明治 下载文件 使用010 eito…

AICodeHelper - AI编程助手

AICodeHelper是一款AI编程助手&#xff0c;旨在帮助程序员提高他们的编码技能。 简单的像尝试的代码直接问就行&#xff0c;但是一些复杂的&#xff0c;就得需要写技巧&#xff1b; 下面是几个使用的小技巧&#xff1a;链接是&#xff1a;AICodeHelper 1.可以使用中文提问&a…

深度学习Faster-RCNN网络

目录1 网络工作流程1.1 数据加载1.2 模型加载1.3 模型预测过程1.3.1 RPN获取候选区域1.3.2 FastRCNN进行目标检测2 模型结构详解2.1 backbone2.2 RPN网络2.2.1 anchors2.2.2 RPN分类2.2.3 RPN回归2.2.4 Proposal层2.4 ROIPooling2.5 目标分类与回归3 FasterRCNN的训练3.1 RPN网…

Yolov5移植树莓派实现目标检测

Hallo&#xff0c;大家好啊&#xff01;之前写了几篇Yolov5相关项目的博客&#xff0c;然后学习了树莓派之后&#xff0c;更新了几篇树莓派的博客&#xff0c;我的最终目的是将Yolov5移植到树莓派&#xff0c;通过树莓派上面的摄像头实现目标检测。你想啊&#xff0c;在工厂里面…

【word文档使用方法记录】论文格式修改

word文档使用方法记录**去掉文档都以也封面的页眉&#xff1a;****WPS公式居中&#xff0c;公式号右对齐**为论文每个章节设置不同的页眉去掉文档都以也封面的页眉&#xff1a; 将光标定位在第一页页尾&#xff0c;进入“页面布局”选项卡&#xff0c;点击“分隔符”&#xff…

【MySQL数据库入门】:数据库基础和基本操作

文章目录1. 数据库基础1.1 什么是数据库1.2 主流数据库1.3 如何配置环境1.4 链接数据库1.5服务器&#xff0c;数据库&#xff0c;表关系2.基本的数据库操作3.MySQL架构4.SQL分类5.存储引擎5.1查看存储引擎5.2 存储引擎对比6.总结1. 数据库基础 1.1 什么是数据库 存储数据用文…

安装包UI美化之路-在线安装包

在一些安装场景中&#xff0c;由于完整的安装包很大&#xff0c;下载时间长&#xff0c;且下载后需要人工干预来进行安装&#xff0c;这样会一定程度的降低用户使用体验&#xff1b;nsNiuniuSkin安装包制作解决方案提供了一种在线版本的安装包&#xff0c;支持将实际要安装的内…

C++中delete 和 delete []的真正区别

1.我们通常从教科书上看到这样的说明&#xff1a; delete 释放new分配的单个对象指针指向的内存 delete[] 释放new分配的对象数组指针指向的内存 那么&#xff0c;按照教科书的理解&#xff0c;我们看下下面的代码&#xff1a; int *a new int[10]; delete a; //方…