线性时间非比较类排序之桶排序

桶排序

桶排序也叫箱排序,1956年便开始使用,它可以算是计数排序的一个改进版本。

1. 算法思想

根据元素的特性将集合拆分为多个值域,我们称之为桶,将同一值域的元素存放在同一个桶内并进行桶内排序使其处于有序状态。如果每个桶是有序的,则由这些桶按顺序构成的集合也必定是有序的。

2. 算法步骤

(1)根据待排序序列中元素的分布特征和差值范围,确定映射函数与申请桶的个数。
(2)遍历序列,将每个记录放到对应的桶中。
(3)选取排序方法,对不为空的桶进行内部排序。
(4)把已排序的桶中的元素放回己清空的原序列中。

3.算法分析

其实,对于桶排序的把握还是比较难的,因片桶排序有点像快速排序又有点像计数排序。
桶排序与快速排序的区别如下:

  • 快速排序是两个分区的排序,而桶排序是多个分区;
  • 快速排序是原地排序方式,即在数组本身内进行排序,而桶排序是在申请的额外的操作空间中进行排序;
  • 快速排序中每个分区的排序方式依然是快速排序,而桶排序则可以自主选择恰当的排序算法进行桶内排序。

桶排序与计数排序的区别如下:

  • 计数排序申请空间的跨度是从最小元素到最大元素,受待排序序列范围的影响很大,而桶排序则弱化了这种影响,这样就减少了元素大小不连续时计数排序所存在的空间浪费情况。

总结一下,桶排序有两个关键点:元素值域的划分和排序算法的选择。

元素值域的划分也就是元素到桶的映射规则,需要根据待排序序列的分布特性进行分析和选择。如果规则设计得过于模糊和笼统,所有待排序元素可能会映射到同一个桶中,则桶排序向比较排序算法演变;如果映射规则过于具体和严苛,每一个待排序元素可能会单独映射到一个桶中,则桶排序向计数排序算法演变。
排序算法的选择是指在进行桶内排序时,可以自主选择任意的排序算法。桶排序的复杂度和稳定性根据桶内排序算法的不同而不同。
在桶排序算法中,时间复杂度分为两部分:映射过程和桶内排序及回填数组过程。映射过程涉及每个元素,所以时间复杂度为O(n);排序过程的时间复杂度是由选取的排序算法和桶的个数决定的,由于这里选取的是堆排序算法,并且有n个待排序元素和m个桶,每个桶中平均有 n m \frac{n}{m} mn个数据,所以时间复杂度为:
O { m . n m l o g 2 n m + n } = O ( n ( l o g 2 n − l o g 2 m ) + n ) O\{m.\frac{n}{m}log_2\frac{n}{m}+n\}=O(n(log_2n-log_2m)+n) O{m.mnlog2mn+n}=O(n(log2nlog2m)+n)
当桶数等于元素个数,即 m=n时,桶排序向计数排序演变,推排序不起作用,复杂度为o(n);当桶数为1,即m=1时,桶排序向比较排序算法演变,对整个集合进行堆排序并回填,复杂度为 O ( n + n l o g 2 n ) O(n+nlog_2n) O(n+nlog2n)
由于桶排序算法需要额外申请空间进行分桶操作,所以空间复杂度为O(n+m)。显而易见,当待排序元素的差值范围较大时,可能会导致绝大多数桶为全桶的现系。从而造成极大的很费,并且对算法的时间复杂度和空间复杂度都有较大的影响,所以和计数排序一样,桶排序适用于元素值分布较集中的序列,数据均匀分布是最好的。

4. 算法代码

算法代码如下:
Python

# -*- coding: utf-8 -*-def heap_sort(array) :"""这里需要注意两点:(1)递归思想(2)列表切片"""length = len(array)#当数组 array 的长度为1时,说明只有一个元素if length<= 1:#无须排序,直接返回原列表return array# 若存在两个或以上节点else:#调整成大顶堆:按照先从下往上,再从左到右的顺序进行调整# 从最后一个非叶子节点(length//2-1)开始向前遍历,直到根节点for i in range(length//2-1,-1,-1):# //为取整# 当左孩儿大于父节点时if array[2*i+1] > array[i]:#二者交換位置array[2*i+1],array[i]=array[i],array[2*i+1] # 如果右孩儿存在且大于父节点时if 2*i+2 <= length-1:if array[2*i+2]> array[i]:#二者交換位置array[2*i+2],array[i] = array[i], array[2*i+2]'''此处省略重构建过程,对结果并不影响!'''# 将堆顶元素与末尾元素进行交换,使最大元素“沉”到数组末尾array[0],array[length-1] = array[length-1], array[0]#递归调用 heap_sort函数对前n-1个元素进行堆排序并返回排序后的结果b=heap_sort(array[0:length-1])return  b + array[length-1:]#桶排序
def bucket_sort (arr) :maximum, minimum = max (arr), min (arr)# 确定桶的个数buckets = [[] for i in range((maximum-minimum) // 10 + 1)]for i in arr:# 计算各元素所属的桶位index = (i- minimum)// 10# list.append()—添加元素buckets[index]. append(i)# 将原数组清空arr.clear ()for i in buckets:# 桶内排序—堆排序(详情见堆排列的内容)i = heap_sort(i)# 将已排序的桶重新放回已清空的原数组中arr.extend(i)return arr
#调用 bucket_sort 函数
print(bucket_sort([34, 21, 13, 2,5,1,55,3,1,8]))

Java

    public static void bucketSort(int[] arr) {// 确定最大值和最小值int maximum = Arrays.stream(arr).max().getAsInt();int minimum = Arrays.stream(arr).min().getAsInt();// 初始化桶列表ArrayList<ArrayList<Integer>> buckets = new ArrayList<>();for (int i = 0; i < (maximum - minimum) / 10 + 1; i++) {buckets.add(new ArrayList<>());}// 将元素放入对应的桶中for (int i : arr) {int index = (i - minimum) / 10;buckets.get(index).add(i);}// 清空原数组并初始化计数器Arrays.fill(arr, 0);int insertIndex = 0;// 对每个桶内部进行堆排序(这里假设已经实现了heapSort方法)for (ArrayList<Integer> bucket : buckets) {bucket.sort(null); // 使用自然顺序排序,此处也可以替换为自定义的堆排序实现for (int num : bucket) {// 将已排序的桶中的元素重新放回原数组arr[insertIndex++] = num;}}}@Testvoid contextLoads () {int[] arr = {34, 21, 13, 2, 5, 1, 55, 3, 1, 8};bucketSort(arr);System.out.println(Arrays.toString(arr));}

5. 输出结果

代码输出结果如下:
在这里插入图片描述

6. 算法过程分解

在这里插入图片描述

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

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

相关文章

华为 Huawei 交换机 黑洞MAC地址的作用和配置示例

黑洞mac作用&#xff1a;某交换机上配置某个PC的mac地址为黑洞mac&#xff0c;那么这台PC发出来的包都会被交换机丢弃&#xff0c;不会被转发到网络中。 组网需求&#xff1a; 如 图 2-13 所示&#xff0c;交换机 Switch 收到一个非法用户的访问&#xff0c;非法用户的 MAC 地址…

Docker容器监控-CIG

目录 一、CIG说明 1. CAdvisor 2. InfluxDB 3. Grafana 二、环境搭建 1. 创建目录 2. 编写 docker-compose.yml 3. 检查并运行容器 三、进行测试 1. 查看 influxdb 存储服务 是否能正常访问 2. 查看 cAdvisor 收集服务能否正常访问 3. 查看 grafana 展现服务&#…

Java毕业设计-基于springboot的网上书店管理系统-第75期

获取源码资料&#xff0c;请移步从戎源码网&#xff1a;从戎源码网_专业的计算机毕业设计网站 项目介绍 基于springboot的网上书店管理系统&#xff1a;前端thymeleaf、js、layui&#xff0c;后端 maven、springmvc、spring、mybatis&#xff0c;集成书籍管理、分类管理、订单…

Windows 安装 MySQL 最新最简教程

Windows 安装 MySQL 最新最简教程 官网地址 https://dev.mysql.com/downloads/mysql/下载 MySQL zip 文件 配置 MySQL1、解压文件 2、进入 bin 目录 搜索栏输入 cmd 回车进入命令行 C:\Users\zhong\Desktop\MySQL\mysql-8.3.0-winx64\mysql-8.3.0-winx64\bin 注意这里是你自己…

Java学习网络编程

Java学习网络编程 大纲 网络相关概念IP地址网络协议InetAdressSocket 具体案例 1. 网络相关概念 网络 网络通信 2. IP地址 域名 3.网络协议 4. InetAdress 获得本机的名字和IP public static void main(String[] args) throws UnknownHostException {InetAddress inetA…

【数据分享】1929-2023年全球站点的逐年平均风速(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、能见度等指标&#xff0c;说到气象数据&#xff0c;最详细的气象数据是具体到气象监测站点的数据&#xff01; 有关气象指标的监测站点数据&#xff0c;之前我们分享过1929-2023年全球气象站…

platform tree架构下i2c应用实例(HS3003)

目录 概述 1 探究platform tree下的i2c 1.1 platform tree下的i2c驱动 1.2 查看i2c总线下的设备 1.3 使用命令读写设备寄存器 2 认识HS3003 2.1 HS3003特性 2.2 HS3003寄存器 2.2.1 温湿度数据寄存器 2.2.2 参数寄存器 2.2.3 一个参数配置Demo 2.3 温湿度值转换 2.…

移动端设置position: fixed;固定定位,底部出现一条缝隙,不知原因,欢迎探讨!!!

1、问题 在父盒子中有一个子盒子&#xff0c;父盒子加了固定定位&#xff0c;需要子盒子上下都有要边距&#xff0c;用margin或者padding挤开时&#xff0c;会出现缝隙是子盒子背景颜色的。 测试过了&#xff0c;有些手机型号有&#xff0c;有些没有&#xff0c;微信小程序同移…

LeetCode 0993. 二叉树的堂兄弟节点:深度优先搜索(BFS)

【LetMeFly】993.二叉树的堂兄弟节点&#xff1a;深度优先搜索(BFS) 力扣题目链接&#xff1a;https://leetcode.cn/problems/cousins-in-binary-tree/ 在二叉树中&#xff0c;根节点位于深度 0 处&#xff0c;每个深度为 k 的节点的子节点位于深度 k1 处。 如果二叉树的两个…

java_error_in_pycharm.hprof文件是什么?能删除吗?

java_error_in_pycharm.hprof文件是什么&#xff1f;能删除吗&#xff1f; &#x1f335;文章目录&#x1f335; &#x1f333;引言&#x1f333;&#x1f333;hprof格式文件介绍&#x1f333;&#x1f333;java_error_in_pycharm.hprof文件什么情况下能删除&#x1f333;&…

【Nicn的刷题日常】之有序序列合并

1.题目描述 描述 输入两个升序排列的序列&#xff0c;将两个序列合并为一个有序序列并输出。 数据范围&#xff1a; 1≤&#xfffd;,&#xfffd;≤1000 1≤n,m≤1000 &#xff0c; 序列中的值满足 0≤&#xfffd;&#xfffd;&#xfffd;≤30000 0≤val≤30000 输入描述…

Java 将TXT文本文件转换为PDF文件

与TXT文本文件&#xff0c;PDF文件更加专业也更适合传输&#xff0c;常用于正式报告、简历、合同等场合。项目中如果有使用Java将TXT文本文件转为PDF文件的需求&#xff0c;可以查看本文中介绍的免费实现方法。 免费Java PDF库 本文介绍的方法需要用到Free Spire.PDF for Java…

波卡 2023 四季度报告:开发者数量位列加密生态前三,五项新技术将于今年发布

作者&#xff1a;Nicholas Garcia&#xff5c;Messari 研究分析师 编译&#xff1a;OneBlock 原文&#xff1a;https://messari.io/report/state-of-polkadot-q4-2023?utm_mediumorganic_social&utm_sourcetwitter_messari&utm_campaignstate_of_polkadot_q4_2023 …

07:Kubectl 命令详解|K8S资源对象管理|K8S集群管理(重难点)

Kubectl 命令详解&#xff5c;K8S资源对象管理&#xff5c;K8S集群管理 kubectl管理命令kubectl get 查询资源常用的排错命令kubectl run 创建容器 POD原理pod的生命周期 k8s资源对象管理资源文件使用资源文件管理对象Pod资源文件deploy资源文件 集群调度的规则扩容与缩减集群更…

Mysql-Explain-使用说明

Explain 说明 explain SELECT * FROM tb_category_report;id&#xff1a;SELECT识别符&#xff0c;这是SELECT查询序列号。select_type&#xff1a;表示单位查询的查询类型&#xff0c;比如&#xff1a;普通查询、联合查询(union、union all)、子查询等复杂查询。table&#x…

[设计模式Java实现附plantuml源码~行为型]请求的链式处理——职责链模式

前言&#xff1a; 为什么之前写过Golang 版的设计模式&#xff0c;还在重新写Java 版&#xff1f; 答&#xff1a;因为对于我而言&#xff0c;当然也希望对正在学习的大伙有帮助。Java作为一门纯面向对象的语言&#xff0c;更适合用于学习设计模式。 为什么类图要附上uml 因为很…

多维时序 | Matlab实现RF-Adaboost随机森林结合Adaboost多变量时间序列预测

多维时序 | Matlab实现RF-Adaboost随机森林结合Adaboost多变量时间序列预测 目录 多维时序 | Matlab实现RF-Adaboost随机森林结合Adaboost多变量时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现RF-Adaboost随机森林结合Adaboost多变量时间序列预…

YOLOv8改进 | 利用训练好权重文件计算YOLOv8的FPS、推理每张图片的平均时间(科研必备)

一、本文介绍 本文给大家带来的改进机制是利用我们训练好的权重文件计算FPS,同时打印每张图片所利用的平均时间,模型大小(以MB为单位),同时支持batch_size功能的选择,对于轻量化模型的读者来说,本文的内容对你一定有帮助,可以清晰帮你展示出模型速度性能的提升以及轻量…

极致成本,如何基于容器计算服务 ACS 打造企业级幻兽帕鲁私服 SaaS 服务?

作者&#xff1a;韩运韬&#xff08;青炽&#xff09; 《幻兽帕鲁》是一款最近大热的开放世界生存游戏。据报道。上市不到一周&#xff0c;《幻兽帕鲁》销量已突破 700 万份&#xff0c;成为名副其实的现象级游戏。根据游戏数据库网站 SteamDB 的数据显示&#xff0c;《幻兽帕…

QTabWidget和QTabBar控件样式设置(qss)

QTabWidget和QTabBar控件样式设置 1、QTabWidget样式可自定义的有哪些示例&#xff1a;效果图 2、QTabBar样式可自定义的有哪些示例效果图 1、QTabWidget样式可自定义的有哪些 QTabWidget::pane{} 定义tabWidgetFrameQTabWidget::tab-bar{} 定义TabBar的位置QTabWidget::tab{}定…