(十二)Java算法:桶排序(详细图解)

news2024/11/24 11:15:00

目录

    • 一、前言
      • 1.1、概念
      • 1.2、算法步骤
    • 二、maven依赖
    • 三、流程解析
      • 3.1、桶编号计算
      • 3.2、桶元素排序
    • 四、编码实现

一、前言

1.1、概念

   计数排序:的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数

1.2、算法步骤

  • 找出待排序的数组中的最大元素max和最小元素min
  • 根据指定的桶数创建桶,本文使用的桶是List结构,桶里面的数据也采用List结构存储
  • 根据公式遍历数组元素:桶编号 = (数组元素 - 最小值) * (桶个数 - 1) / (最大值 - 最小值),把数据放到相应的桶中
  • 从小到大遍历每一个桶,同时对桶里的元素进行排序
  • 把排好序的元素从索引为0开始放入(因为前一个桶的数据一定小于后一个桶的数据,然后每个桶里的数据又是有序的),完成排序

二、maven依赖

pom.xml

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <version>2.6.0</version>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.16.14</version>
    </dependency>
</dependencies>

三、流程解析

  假设我们要排序的数据是:15, 8, 23, 38, 28, 19, 32, 21, 9

3.1、桶编号计算

  通过我们的整体流程图,来看看数据是怎么分,又是怎么合成的。

  桶编号 = (数组元素 - 最小值) * (桶个数 - 1) / (最大值 - 最小值)

数组索引数组数据计算桶编号
015 ( 15 − 8 ) ∗ ( 4 − 1 ) ( 38 − 8 ) = 0 \frac{(15 - 8) * (4 - 1)}{(38 - 8)}=0 (388)(158)(41)=0
18 ( 8 − 8 ) ∗ ( 4 − 1 ) ( 38 − 8 ) = 0 \frac{(8 - 8) * (4 - 1)}{(38 - 8)}=0 (388)(88)(41)=0
223 ( 23 − 8 ) ∗ ( 4 − 1 ) ( 38 − 8 ) = 1 \frac{(23 - 8) * (4 - 1)}{(38 - 8)}=1 (388)(238)(41)=1
338 ( 38 − 8 ) ∗ ( 4 − 1 ) ( 38 − 8 ) = 3 \frac{(38 - 8) * (4 - 1)}{(38 - 8)}=3 (388)(388)(41)=3
428 ( 28 − 8 ) ∗ ( 4 − 1 ) ( 38 − 8 ) = 2 \frac{(28 - 8) * (4 - 1)}{(38 - 8)}=2 (388)(288)(41)=2
519 ( 19 − 8 ) ∗ ( 4 − 1 ) ( 38 − 8 ) = 1 \frac{(19 - 8) * (4 - 1)}{(38 - 8)}=1 (388)(198)(41)=1
632 ( 32 − 8 ) ∗ ( 4 − 1 ) ( 38 − 8 ) = 2 \frac{(32 - 8) * (4 - 1)}{(38 - 8)}=2 (388)(328)(41)=2
721 ( 21 − 8 ) ∗ ( 4 − 1 ) ( 38 − 8 ) = 1 \frac{(21 - 8) * (4 - 1)}{(38 - 8)}=1 (388)(218)(41)=1
89 ( 9 − 8 ) ∗ ( 4 − 1 ) ( 38 − 8 ) = 0 \frac{(9 - 8) * (4 - 1)}{(38 - 8)}=0 (388)(98)(41)=0

  根据计算把数据放到相应的桶中,如下图所示:

在这里插入图片描述

3.2、桶元素排序

  接下里我们对桶里的元素进行排序,我这里为了省事就采用自带的排序了,排序结果如下:

在这里插入图片描述
  你可以使用其他任意排序算法进行(比如快速排序,插入排序等等),当然这里递归使用桶排序也是可以的。

四、编码实现

/**
 * 桶排序
 *
 * @param arr
 * @param bucketSize
 */
public static void bucketsort(int[] arr, int bucketSize) {
    // 初始化最大最小值
    int max = Integer.MIN_VALUE;
    int min = Integer.MAX_VALUE;
    // 找出最小值和最大值
    for (int num : arr) {
        max = Math.max(max, num);
        min = Math.min(min, num);
    }

    // 创建bucketSize个桶
    List<List<Integer>> bucketList = new ArrayList<>();// 声明五个桶
    for (int i = 0; i < bucketSize; i++) {
        bucketList.add(new ArrayList<>());// 确定桶的格式为ArrayList
    }

    // 将数据放入桶中
    for (int num : arr) {
        // 确定元素存放的桶号
        int bucketIndex = (num - min) * (bucketSize - 1) / (max - min);//重点
        log.info("({} - {}) * ({} - 1) / ({} - {})={}", num, min, bucketSize, max, min, bucketIndex);
        log.info("【{}】放入到第【】号桶中:{}", num, bucketIndex + 1);
        List<Integer> list = bucketList.get(bucketIndex);
        list.add(num);// 将元素存入对应的桶中

    }
    // 遍历每一个桶
    for (int i = 0, arrIndex = 0; i < bucketList.size(); i++) {
        List<Integer> list = bucketList.get(i);
        log.info("第【{}】桶的数据为:{}", i + 1, list);
        list.sort(null);// 对每一个桶排序
        for (int value : list) {
            arr[arrIndex++] = value;
        }
    }
}

public static void main(String[] args) {
    int[] arr = {15, 8, 23, 38, 28, 19, 32, 21, 9};
    log.info("要排序的初始化数据:{}", arr);
    //从小到大排序
    bucketsort(arr, 4);
    log.info("结果为:{}", arr);
}

运行结果:

要排序的初始化数据:[15, 8, 23, 38, 28, 19, 32, 21, 9]
(15 - 8) * (4 - 1) / (38 - 8)=0
【15】放入到第【】号桶中:1
(8 - 8) * (4 - 1) / (38 - 8)=0
【8】放入到第【】号桶中:1
(23 - 8) * (4 - 1) / (38 - 8)=1
【23】放入到第【】号桶中:2
(38 - 8) * (4 - 1) / (38 - 8)=3
【38】放入到第【】号桶中:4
(28 - 8) * (4 - 1) / (38 - 8)=2
【28】放入到第【】号桶中:3
(19 - 8) * (4 - 1) / (38 - 8)=1
【19】放入到第【】号桶中:2
(32 - 8) * (4 - 1) / (38 - 8)=2
【32】放入到第【】号桶中:3
(21 - 8) * (4 - 1) / (38 - 8)=1
【21】放入到第【】号桶中:2
(9 - 8) * (4 - 1) / (38 - 8)=0
【9】放入到第【】号桶中:1
第【1】桶的数据为:[15, 8, 9]
第【2】桶的数据为:[23, 19, 21]
第【3】桶的数据为:[28, 32]
第【4】桶的数据为:[38]
结果为:[8, 9, 15, 19, 21, 23, 28, 32, 38]

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

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

相关文章

SpringCloud全系列知识(2)—— Nacos配置和集群

Nacos配置和集群 一 统一配置管理 Nacos官方文档 1.配置热更新 1.新建配置文件 在Nacos的配置列表中新建一个配置文件。 注意事项&#xff1a; Data ID 命名规则&#xff1a;一般情况下使用使用 “微服务名称运行环境” 作为DataID&#xff0c;后缀名建议使用文件后缀全…

集成一个以官网(微信,QQ,微博)为标准的登录分享功能

Hello&#xff0c;各位老铁&#xff0c;今天要分享的是一个老生常谈的一个功能&#xff0c;也是网上一搜一大片的技术点&#xff0c;没什么技术含量&#xff0c;就是整合一下&#xff0c;提供一下方便&#xff0c;相对于友盟&#xff0c;ShareSdk中夹杂着一些别的功能&#xff…

Python编程 集合

作者简介&#xff1a;一名在校计算机学生、每天分享Python的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.集合 1.集合介绍(掌握) 2.集合创建(掌握) 3.添加元素(熟悉) 4.集合…

区域治理杂志区域治理杂志社区域治理编辑部2022年第40期目录

政策 乡村振兴人才发展战略分析 (1) 高庸江 声音《区域治理》投稿&#xff1a;cnqikantg126.com 迈向智能党建&#xff1a;智能媒体在党建工作中的创新运用 (5) 申娟 经验 北京市昌平区节水问题及水资源利用对策研究 (9) 彭聪 重庆市低碳创新政策优化研究 (13) 林芳 …

怎么把Word翻译成中文?建议收藏这些方法

相信不少小伙伴在撰写论文的时候&#xff0c;都有查阅大量的国内外文献吧。有时由于国外文献里面会含有大量的深奥词汇&#xff0c;我们一时半会儿没法马上理解文献的内容。其实我们可以使用软件直接翻译Word文档&#xff0c;那你们知道Word文档怎么翻译吗&#xff1f;有需要对…

【Android App】实战项目之仿抖音的短视频分享App(附源码和演示视频 超详细必看)

需要全部代码请点赞关注收藏后评论区留言私信~~~ 与传统的影视行业相比&#xff0c;诞生于移动互联网时代的短视频是个全新行业&#xff0c;它制作方便又容易传播&#xff0c;一出现就成为大街小巷的时髦潮流。 各行各业的人们均可通过短视频展示自己&#xff0c;短小精悍的视频…

网络面试-0x12 UDP和TCP的区别以及应用场景

一、 UDP &#xff08;user datagram protocol&#xff09;用户数据报协议 ①&#xff1a; 一种简单的面向数据报的通讯协议&#xff0c;即&#xff1a;应用层传下来的报文&#xff0c;不合并&#xff0c;不拆分&#xff0c;只是在其上面加上首部后就交给了下面的网络层。无论应…

Github优秀项目-使用Python基于CPM文本自动生成

基于CPM模型的中文文本生成项目,可用于作文、小说、新闻、古诗等中文生成任务。 虽然说开源的,但是实际部署应用的过程中很多小伙伴还遇见了不少的问题,这里我用自己的方式部署应用,如果还没有实现该功能的小伙伴可以跟我一起来操作。 如果有不了解的小伙伴先来看一下实验…

【多目标进化优化】多目标进化算法的收敛性

0 前言 \quad\quad对 MOEAMOEAMOEA 收敛性的研究是 MOEAMOEAMOEA 研究的重要内容&#xff0c;但目前这方面的研究结果比较少。 一个 MOEAMOEAMOEA 的收敛性可以从两个方面考虑&#xff1b;一是有限时间内的收敛&#xff1b;二是当时间趋向于无穷大时的收敛。第一类收敛是最理想…

Kotlin高仿微信-第9篇-单聊-文本

Kotlin高仿微信-项目实践58篇详细讲解了各个功能点&#xff0c;包括&#xff1a;注册、登录、主页、单聊(文本、表情、语音、图片、小视频、视频通话、语音通话、红包、转账)、群聊、个人信息、朋友圈、支付服务、扫一扫、搜索好友、添加好友、开通VIP等众多功能。 Kotlin高仿…

麦芽糖-阿奇霉素 maltose-Azithromycin 阿奇霉素-PEG-麦芽糖

麦芽糖-阿奇霉素 maltose-Azithromycin 阿奇霉素-PEG-麦芽糖 中文名称&#xff1a;麦芽糖-阿奇霉素 英文名称&#xff1a;maltose-Azithromycin 别称&#xff1a;阿奇霉素修饰麦芽糖&#xff0c;阿奇霉素-麦芽糖 纯度&#xff1a;95% 存储条件&#xff1a;-20C&#xff0c…

webscoket学习

webscoket基本使用 WebSocket - Web API 接口参考 | MDN 使用node编写webscoket服务 nodejs-webscoket 在github的地址↓ GitHub - sitegui/nodejs-websocket: A node.js module for websocket server and client ws和socket.io 是wbscket的两个库 仓库地址&#xff1a;l…

Scala系列-5、scala中的泛型、actor、akka

版权声明&#xff1a;本文为博主原创文章&#xff0c;遵循 CC 4.0 BY-SA 版权协议&#xff0c;转载请附上原文出处链接和本声明。 传送门&#xff1a;大数据系列文章目录 目录scala的 泛型给方法定义泛型给类定义泛型泛型的上下界泛型中 非变 协变 和 逆变scala中actor相关内…

echarts中tooltip设为渐变色与模糊背景滤镜

关于echarts各项内容&#xff08;包括图表面积区域&#xff09;设为渐变色已在上篇文章里全部阐述&#xff1a; echarts折线图与柱状图等绘成渐变色的方法 单独将tooltip拉出来再写一篇&#xff0c;是因为用formatter配合超文本的形式在echarts的配置项中&#xff0c;于自定义样…

Python使用magic判断文件MIME类型

文章目录官网安装使用判断文件的MIME类型支持中文的代码问题官网 GitHub - ahupp/python-magic: A python wrapper for libmagic 安装 pip install python-magic pip install python-magic-bin使用 判断文件的MIME类型 代码 # encodingutf-8 import magic #pip install pyt…

希尔贝壳受邀参加IEEE自动语音识别与理解研讨会-ASRU 2021

ASRU 2021 IEEE Automatic Speech Recognition and Understanding Workshop&#xff08;2021年IEEE自动语音识别与理解研讨会&#xff0c;以下简称ASRU&#xff09;&#xff0c;将于2021年12月13日至17日在哥伦比亚卡塔赫纳举行。 ASRU 研讨会是IEEE语音和语言处理技术委员会(…

领悟《信号与系统》之 周期信号的傅里叶变换计算

周期信号的傅里叶变换计算一、周期信号的傅里叶变换存在的条件二、周期信号的傅里叶变换例题&#xff1a;一、周期信号的傅里叶变换存在的条件 典型非周期信号&#xff08;如指数信号&#xff0c;矩形信号等&#xff09;都是满足绝对可积&#xff08;或绝对可和&#xff09;条…

IDEA的日常快捷键大全

更多内容在&#xff1a;https://javaxiaobear.gitee.io/ ​​​​​​第1组&#xff1a;通用型 说明 快捷键 复制代码-copy ctrl c 粘贴-paste ctrl v 剪切-cut ctrl x 撤销-undo ctrl z 反撤销-redo ctrl shift z 保存-save all ctrl s 全选-select all …

(2)点云库处理学习——剔除点云值

1、主要参考 1.1参考地址 (1) 点云离群点剔除 — open3d python_Coding的叶子的博客-CSDN博客_离群点去除 (2) open3d之点云异常值去除&#xff08;笔记5&#xff09;_Satellite_H的博客-CSDN博客 (3)斯坦福经典兔子的点云数据下载地址 下载地址 Model : Bunny 1.2兔子…

3D视觉识别案例:3D无序棒料抓取,阀体圆环上下料,电机定子上料

3D无序棒料抓取 某知名汽车行业 项目背景 长春某知名汽车行业&#xff0c;需求3D视觉实现圆形棒材的上料自动化。 作业流程 钢棒依次经过剪切/锯切下料&#xff0c;从深筐中抓取&#xff0c;先放置在V型二次定位平台上&#xff0c;再从平台抓到输送线上&#xff0c;目标工…