桶排序和基数排序

前言:

        这篇文章,我们就来了解一些鲜为人知的排序,桶排序和基数排序。

桶排序:

桶排序的思想:

        桶排序的思想就是把待排序的数尽量均匀地放到各个桶中,再对各个桶进行局部的排序,最后再按序将各个桶中的数输出,即可得到排好序的数。

        桶排序(Bucket Sort)又称箱排序,是一种比较常用的排序算法。其算法原理是将数组分到有限数量的桶里,再对每个桶分别排好序(可以是递归使用桶排序,也可以是使用其他排序算法将每个桶分别排好序),最后一次将每个桶中排好序的数输出。

        首先确定桶的个数。因为桶排序最好是将数据均匀地分散在各个桶中,那么桶的个数最好是应该根据数据的分散情况来确定。首先找出所有数据中的最大值max和最小值min;

求桶的个数: 

        根据max和min确定每个桶所装的数据的范围 size,有size = (max - min) / n + 1,n为数据的个数,需要保证至少有一个桶,故而需要加个1;

求桶数据范围差值:

        求得了size即知道了每个桶所装数据的范围,还需要计算出所需的桶的个数count,有
count = (max - min) / size + 1,需要保证每个桶至少要能装1个数,故而需要加个1;

桶的数据范围:

        求得了size和cnt后,即可知第一个桶装的数据范围为 [min, min + size),第二个桶为 [min + size, min + 2 * size),…,以此类推。

        因此步骤2中需要再扫描一遍数组,将待排序的各个数放进对应的桶中。

对桶中的元素进行排序: 

        对各个桶中的数据进行排序,可以使用其他的排序算法排序,例如快速排序;也可以递归使用桶排序进行排序;

统一排序:

        最后将各个桶中排好序的数据依次输出,最后得到的数据即为最终有序。

图解:

接下来举一个例子:

例如,待排序的数为:3, 6, 9, 1

1)求得 max = 9,min = 1,n = 4
size = (9 - 1) / n + 1 = 3
count = (max - min) / size + 1 = 3

2)由上面的步骤可知,共3个桶,每个桶能放3个数,第一个桶数的范围为 [1, 4),第二个[4, 7),第三个[7, 10)
扫描一遍待排序的数,将各个数放到其对应的桶中,放完后如下图所示:

3)对各个桶中的数进行排序,得到如下图所示:

4)依次输出各个排好序的桶中的数据,即为:1, 3, 6, 9
可见,最终得到了有序的排列。

代码: 

    public static void barrelSort(int[] nums) {int n = nums.length;int max = 0, min = 0;//找出最大最小值for (int i = 0; i < n; i++) {if (nums[i] > max) {max = nums[i];}if (nums[i] < min) {min = nums[i];}}int size = (max - min) / n + 1;//获取桶的个数,至少保证有一个int count = (max - min) / size + 1;//得知每个桶中存取数据范围(相当于差值)List<Integer>[] barrel = new List[size];//初始化每个桶for (int i = 0; i < size; i++) {barrel[i] = new ArrayList<>();}//扫描一遍数组,把数放在对应的桶里面for (int i = 0; i < n; i++) {int index = (nums[i] - min) / size;//定位第几个桶barrel[index].add(nums[i]);}//对同种每个数据进行排序,这里使用快排for (int i = 0; i < size; i++) {barrel[i].sort(null);//默认就是升序排序,不需要使用比较器}//一次出桶int index = 0;for (int i = 0; i < size; i++) {for (int j = 0; j < barrel[i].size(); j++) {nums[index++] = barrel[i].get(j);}}}public static void main(String[] args) {int[] nums = {19,27,35,43,31,22,54,66,78};barrelSort(nums);for (int i = 0; i < nums.length; i++) {System.out.print(nums[i] + " ");}}
}

时间复杂度分析: 

最好时间复杂度:O(n + k)

        其中k为桶的个数。即当数据是均匀分散排列的,那么每个桶分到的数据个数都是一样的,这个步骤需要O(k)的时间复杂度,在对每个桶进行排序的时候,最好情况下是数据都已经是有序的了,那么最好的排序算法的时间复杂度会是O(n),因此总的时间复杂度是 O(n + k) 。

最坏时间复杂度:O(n^2)

        当对每个桶中的数据进行排序的时候,所使用的排序算法,最坏情况下是O(n^2).

平均时间复杂度:O(n)

基数排序:

基数排序的思想:

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

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

相关文章

AI Agent: Agent框架+7个实例

何谓Agent Agent 作为一种新兴的人工智能技术&#xff0c;正在受到越来越多的关注。要说清楚什么是 Agent&#xff0c;先得看看人工智能的本质是什么。 人工智能这个名称来自它试图通过计算机程序或机器来模拟、扩展和增强人类智能的 一些方面。在这个定义中&#xff0c;“人…

C# WPF入门学习(四)—— 按钮控件

上期介绍了WPF的实现架构和原理&#xff0c;之后我们开始来使用WPF来学习各种控件。 一、尝试插入一个按钮&#xff08;方法一&#xff09; 1. VS2019 在界面中&#xff0c;点击工具栏中的视图&#xff0c;在下拉菜单中选择工具箱。 至于编译器中的视图怎么舒服怎么来布置&am…

Cocos Creator 帧动画播放组件制作详解

Cocos Creator 是一个强大的游戏开发工具&#xff0c;提供了丰富的功能和组件&#xff0c;其中帧动画播放组件是游戏开发中常用的组件之一&#xff0c;通过帧动画播放组件可以实现角色动画、特效动画等效果。本文将详细介绍如何使用 Cocos Creator 制作帧动画播放组件&#xff…

infoq学习笔记-云原生网关当道,三大主流厂商如何“竞 技”?

注基础组件的质量&#xff0c;这些基础组件是用户看不到的。这些组件包括代码质量、自动化的CI/CD、端对端测试、混沌测试等。在APISIX中&#xff0c;我们内置了大 量的测试案例代码&#xff0c;包括单元测试、E2E测试、混沌测试&#xff0c;以及一些基准测试等&#xff0c;从而…

沈阳师范大学文学院副教授傅赢

女&#xff0c;生于1971年6月&#xff0c;辽宁辽阳人&#xff0c;1995年6月毕业于沈阳师范学院中文系汉语言文学教育专业&#xff0c;2000年6月于东北师范大学获中国现当代文学专业文学硕士学位&#xff0c;现为文学院汉语国际教育专业教师&#xff0c;副教授。 主要从事对外汉…

蓝桥杯练习系统(算法训练)ALGO-934 序列

资源限制 内存限制&#xff1a;256.0MB C/C时间限制&#xff1a;1.0s Java时间限制&#xff1a;3.0s Python时间限制&#xff1a;5.0s 问题描述 王神想要知道n的所有排列的逆序对数和&#xff0c;但是他觉得太水了&#xff0c;于是让你算。 输入格式 一行一个整数n 输…

random和range

含义&#xff1a; random(1&#xff0c;10) 不包含10&#xff0c;用于生成随机数。它可以生成浮点数或整数&#xff0c;取决于具体的使用方式。 range(0&#xff0c;1) 不包含1&#xff0c;用于生成一个整数序列。它可以生成一个指定范围内的连续整数序列。 区别在于&#x…

Linux:Linux系统项目配置

linux高级 软件安装 rpm(redhat package manager)安装 软件已经按照redhat的包管理规范进行打包,使用rpm命令进行安装,但包之间可能有依赖关系,因此不能自行解决库依赖问题,比较麻烦 yum安装 一种在线软件安装方式,本质上还是rpm安装,自动下载安装包并安装,安装过程中自动…

【MySQL精通之路】SQL优化(1)-查询优化(23)-避免全表扫描

当MySQL使用全表扫描来解析查询时&#xff0c;EXPLAIN的输出在type列中显示ALL。 这种情况通常发生在以下情况下&#xff1a; 该表非常小&#xff0c;因此执行全表扫描比查找关键字更快。这对于少于10行且行长较短的表来说很常见。 对于索引列&#xff0c;ON或WHERE子句中没有…

服务器硬件全攻略:从入门到精通,全面解析服务器性能与稳定性!

服务器是计算机网络中提供特定服务的计算机系统&#xff0c;其硬件配置和性能直接影响到整个网络系统的运行效率和稳定性。作为一个资深的技术人员&#xff0c;本文将全面详细地介绍服务器硬件基础知识&#xff0c;包括介绍、命令或语法、主要作用以及使用方法等。 一、介绍 服…

Linux基础(七):Linux 系统上的库文件生成与使用

学过C语言我们知道&#xff0c;C语言有标准库和自定义库&#xff0c;这些方便了我们的实际开发&#xff0c;提供了已经实现好的函数接口&#xff0c;我们使用的时候&#xff0c;只需要引入头文件即可&#xff0c;那具体的实现过程又是怎么样的呢&#xff1f;我们又该如何实现我…

JS实现照片预览

以下是一个简单的JS代码示例&#xff0c;用于实现照片预览功能&#xff1a; <!DOCTYPE html> <html> <head><title>Photo Preview</title><script>function previewPhoto(event) {var reader new FileReader();reader.onload function(…

MySQL字符数据查询拆分

MySQL字符数据查询拆分 问题描述 数据表中某字段为特定单词组字符串&#xff0c;特定字符分隔。 现有需求&#xff1a;在不影响原始数据的情况下&#xff0c;查询显示拆分后的单词&#xff0c;方便后续对其进行后续操作。 演示 演示数据源 -- 测试表结构create table word_…

Java中创建不可变对象实现细节和例子

当我们在Java中创建不可变对象时&#xff0c;我们需要确保对象的状态在创建之后不能被修改。以下是一些具体的实现细节和例子&#xff0c;展示了如何在Java中创建不可变对象。 实现细节 使用final关键字&#xff1a; 类定义前使用final关键字&#xff0c;表示该类不能被继承&…

Mysql中的慢查询

Mysql慢查询的一些sql命令 慢查询的默认事件为10秒 #注意&#xff1a;慢查询一般是在调试阶段开启的&#xff0c;在开发阶段中一般不会开启&#xff0c;会对效率产生延误 #查询慢查询是否开启 show variables like %general%; #慢查询时间设置 show variables like long_query…

【运维项目经历|018】:Elasticsearch智能数据分析平台项目

目录 项目名称 项目背景 项目目标 项目成果 我的角色与职责 我主要完成的工作内容 本次项目涉及的技术 本次项目遇到的问题与解决方法 本次项目中可能被面试官问到的问题 问题1&#xff1a;本次项目周期&#xff1f; 问题2&#xff1a;服务部署架构方式及数量和配置&…

【简明指南:Python中的异常处理与稳健代码设计】

文章目录 前言异常处理基础捕获多种异常确保资源被释放使用else子句自定义异常结论 前言 软件开发过程中&#xff0c;保证代码的稳健性和可靠性至关重要。异常处理是实现这一目标的关键技术之一。在Python编程中&#xff0c;合理地捕获和处理异常不仅能提高程序的健壮性&#…

查找专利渠道

官方渠道 常规检索 (cnipa.gov.cn)https://pss-system.cponline.cnipa.gov.cn/conventionalSearch 佰腾网 佰腾网 - 查专利就上佰腾网_佰腾全球专利搜索平台_商标查询平台_企业工商信息查询平台 (baiten.cn)https://www.baiten.cn/

NLP(19)--大模型发展(3)

前言 仅记录学习过程&#xff0c;有问题欢迎讨论 大模型训练相关知识&#xff1a; 问题&#xff1a; 数据集过大&#xff0c;快速训练模型过大&#xff0c;gpu跑不完 方案&#xff1a; 数据并行训练&#xff1a; 复制数据&#xff08;batch_size&#xff09;到多个gpu&…

簡述vue-router的動態路由

动态路由 addRoute 是 Vue Router 中的一个功能&#xff0c;它允许你在运行时动态地向路由表添加路由规则。这在一些需要基于用户行为或异步数据加载路由的场景中非常有用。以下是对 addRoute 功能的详细解释和使用示例&#xff1a; 1. 动态路由的概念 动态路由是指在应用运行…