十大排序——9.桶排序

这篇文章我们来介绍一下桶排序

目录

1.介绍

2.代码实现

3.总结与思考


1.介绍

桶排序和计数排序一样,都不是基于比较进行排序的。

下面通过一个例子来理解一下桶排序吧。

首先,给你一个无序数组[ 20,18,28,66,25,31,67,30 ],然后,我们对其进行一个划分,比如十位数为1的放一起排,十位数为2的放一起排等等。结果就是我创造了10个桶,每个桶里面都放着十位数相同的那些数,然后,我在这些桶里再实现这些数据的有序性,然后,我再依次将这些数据取出来,这样就保证了数据的有序性。

下面看一下介绍:

桶排序(Bucket sort)或所谓的箱排序,是一个排序算法,工作的原理是将数组分到有限数量的桶里。每个桶再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序),最后依次把各个桶中的记录列出来记得到有序序列。桶排序是鸽巢排序的一种归纳结果。当要被排序的数组内的数值是均匀分配的时候,桶排序使用线性时间(O(n))。但桶排序并不是比较排序,他不受到 O(n log n) 下限的影响。

基本思想

桶排序的思想近乎彻底的分治思想

桶排序假设待排序的一组数均匀独立的分布在一个范围中,并将这一范围划分成几个子范围(桶)。

然后基于某种映射函数 f ,将待排序列的关键字 k 映射到第 i 个桶中 (即桶数组 B 的下标 i ) ,那么该关键字 k 就作为 B[ i ] 中的元素 (每个桶B[ i ] 都是一组大小为 N/M 的序列 )。

接着将各个桶中的数据有序的合并起来 : 对每个桶B[ i ] 中的所有元素进行比较排序 (可以使用快排)。然后依次枚举输出 B[ 0 ] …. B[ M ] 中的全部内容即是一个有序序列。

补充: 映射函数一般是 f = array[ i ] / k; k^2 = n;n 是所有元素个数

为了使桶排序更加高效,我们需要做到这两点:

1、在额外空间充足的情况下,尽量增大桶的数量;
2、使用的映射函数能够将输入的 N 个数据均匀的分配到 K 个桶中;

同时,对于桶中元素的排序,选择何种比较排序算法对于性能的影响至关重要。

实现逻辑

  • 设置一个定量的数组当作空桶子。
  • 寻访序列,并且把项目一个一个放到对应的桶子去。
  • 对每个不是空的桶子进行排序。
  • 从不是空的桶子里把项目再放回原来的序列中。

2.代码实现

下面看一下代码实现:

package Sorts;

import java.util.*;

//桶排
public class RadixSort {
    public static void main(String[] args) {
        int [] arr = new int[]{193,255,12,6,78,50,31,564};
        bucketSort(arr);;
        System.out.println(Arrays.toString(arr));

    }

    public static void bucketSort(int[] array) {
        if (array == null || array.length <= 1) {
            return;
        }

        // 建立桶,个数和待排序数组长度一样
        int length = array.length;

        LinkedList<Integer>[] bucket = (LinkedList<Integer>[]) new LinkedList[length];

        // 待排序数组中的最大值
        int maxValue = Arrays.stream(array).max().getAsInt();
        // 根据每个元素的值,分配到对应范围的桶中
        for (int i = 0; i < array.length; i++) {
            int index = toBucketIndex(array[i], maxValue, length);
            // 没有桶才建立桶(延时)
            if (bucket[index] == null) {
                bucket[index] = new LinkedList<>();
            }
            // 有桶直接使用
            bucket[index].add(array[i]);
        }

        // 对每个非空的桶排序,排序后顺便存入临时的List,则list中已经有序)
        List<Integer> temp = new ArrayList<>();
        for (int i = 0; i < length; i++) {
            if (bucket[i] != null) {
                Collections.sort(bucket[i]);
                temp.addAll(bucket[i]);
            }
        }

        // 将temp中的数据写入原数组
        for (int i = 0; i < length; i++) {
            array[i] = temp.get(i);
        }
    }

    private static int toBucketIndex(int value, int maxValue, int length) {
        return (value * length) / (maxValue + 1);
    }
    
    /**
     *
    public static void sort(int arr[] ){
        //定义二维数组
        int [][] bucket = new int[10][arr.length];
        //定义记录桶中数据个数的数组
        int [] bucketElement = new int[10];

        for (int i = 0; i <arr.length ; i++) {
            int element = arr[i] % 10;
            bucket[element][bucketElement[element]] = arr[i];
            bucketElement[element]++;
        }

        int index = 0;

        for (int k = 0; k <bucketElement.length ; k++) {
            if (bucketElement[k]!=0){
                for (int l = 0; l <bucketElement [k] ; l++) {
                    arr[index] = bucket[k][l];
                    index++;
                }
            }
            bucketElement[k]=0;
        }
    }
     */
}

注释的部分可能更好理解一点

3.总结与思考

桶排序是计数排序的变种,它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。把计数排序中相邻的m个”小桶”放到一个”大桶”中,在分完桶后,对每个桶进行排序(一般用快排),然后合并成最后的结果。

算法思想和散列中的开散列法差不多,当冲突时放入同一个桶中;可应用于数据量分布比较均匀,或比较侧重于区间数量时。

桶排序最关键的建桶,如果桶设计得不好的话桶排序是几乎没有作用的。通常情况下,上下界有两种取法,第一种是取一个10^n或者是2^n的数,方便实现。另一种是取数列的最大值和最小值然后均分作桶.

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【GD32】_时钟架构及系统时钟频率配置

文章目录 一、有关时钟源二、系统时钟架构三、时钟树分析四、修改参数步骤1、设置外部晶振2、选择外部时钟源。3、 设置系统主频率大小4、修改PLL分频倍频系数 学习系统时钟架构和时钟树&#xff0c;验证及学习笔记如下&#xff0c;如有错误&#xff0c;欢迎指正。主要记录了总…

【电控笔记2.2】电流回路+延迟效应

延迟效应的来源以及影响 数字控制系统的delay: 5.4节有介绍T0=0.5TS 低通滤波器的时间常数? 滤波器的传递函数与性能参数

C语言入门第四天(数组)

一、C语言数组的基本语法 1.数组的定义 数组是 C 语言中的一种数据结构&#xff0c;用于存储一组具有相同数据类型的数据。数组中的每个元素可以通过一个索引&#xff08;下标&#xff09;来访问&#xff0c;索引从 0 开始&#xff0c;最大值为数组长度减 1。 2.定义语法格式 …

Linux进阶篇:文件传输工具curl命令详解

文件传输工具Linux curl命令详解 一 curl命令介绍 在Linux中curl是一个利用URL规则在命令行下工作的文件传输工具&#xff0c;可以说是一款很强大的http命令行工具。它支持文件的上传和下载&#xff0c;是综合传输工具&#xff0c;但按传统&#xff0c;习惯称url为下载工具。…

leetcode-反转链表

206. 反转链表 题目 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]示例 2&#xff1a; 输入&#xff1a;head [1,2] 输出&#xff1a;[2,1]示例 3…

OpenHarmony南向开发实例:【游戏手柄】

介绍 基于TS扩展的声明式开发范式编程语言&#xff0c;以及OpenHarmony的分布式能力实现的一个手柄游戏。 完成本篇Codelab需要两台开发板&#xff0c;一台开发板作为游戏端&#xff0c;一台开发板作为手柄端&#xff0c;实现如下功能&#xff1a; 游戏端呈现飞机移动、发射…

jenkins构建微信小程序并展示二维码

测试小程序的过程中&#xff0c;很多都是在回头和前端开发说一句&#xff0c;兄弟帮我打一个测试版本的测试码&#xff0c;开发有时间的情况下还好&#xff0c;就直接协助了&#xff0c;但是很多时候他们只修复了其中几个bug&#xff0c;其他需要修复的bug代码正在编写&#xf…

Unity 左右折叠显示与隐藏UI的简单实现

要实现一个简单的UI左右折叠显示与隐藏&#xff0c;可以结合遮罩&#xff0c;通过代码控制UI区块的宽度和位移来实现。 具体可以按以下步骤实现&#xff1a; 1、新建一个Image组件&#xff0c;并添加精灵&#xff0c;调整大小后&#xff0c;复制一份作为该UI的父物体&#xf…

rhce.定时任务和延迟任务项目

一 . 在系统中设定延迟任务要求如下&#xff1a; 在系统中建立 easylee 用户&#xff0c;设定其密码为 easylee 延迟任务由 root 用户建立 要求在 5 小时后备份系统中的用户信息文件到/backup中 确保延迟任务是使用非交互模式建立 确保系统中只有 root 用户和easylee用户可以…

当当图书网数据采集分析:10万条数据的深入洞察

基于搜索结果&#xff0c;我将为您提供一个关于当当图书网数据采集的文章框架&#xff0c;假设我们已经有了10万条数据的采集结果。请注意&#xff0c;由于没有具体的数据文件&#xff0c;以下内容将是一个示例性的框架&#xff0c;您可以根据实际采集到的数据进行填充和调整。…

AI人工智能老师大模型讲师叶梓 OneLLM:开创性的多模态大型语言模型技术

在人工智能领域&#xff0c;多模态大型语言模型&#xff08;MLLM&#xff09;的研究一直是一个热门话题。近期&#xff0c;一种名为OneLLM的创新技术引起了业界的广泛关注。OneLLM通过其独特的统一框架&#xff0c;实现了多种不同模态与自然语言的高效对齐&#xff0c;为多模态…

什么是NAT!

一、NAT&#xff08; network address translation&#xff09; 网络地址翻译 为什么会出现这个技术&#xff0c;目的就是用来解决ipv4 地址不够用的情况&#xff0c;因为在互联网最开始的时候&#xff0c;有一个概念是拥有合法IP地址&#xff0c;每个主机连接到互联网必须要…

Big Data and Cognitive Computing (IF=3.7) 计算机/大数据/人工智能期刊投稿

Special Issue: Artificial Cognitive Systems for Computer Vision 欢迎计算机/大数据/人工智能/计算机视觉相关工作的投稿&#xff01; 影响因子3.7&#xff0c;截止时间2024年12月31日 投稿咨询&#xff1a;lqyan18fudan.edu.cn 投稿网址&#xff1a;https://www.mdpi.com/j…

RK3568笔记二十二:基于TACO的垃圾检测和识别

若该文为原创文章&#xff0c;转载请注明原文出处。 基于TACO数据集&#xff0c;使用YOLOv8分割模型进行垃圾检测和识别&#xff0c;并在ATK-RK3568上部署运行。 一、环境 1、测试训练环境&#xff1a;AutoDL. 2、平台&#xff1a;rk3568 3、开发板: ATK-RK3568正点原子板子…

Ubuntu Vs code配置ROS开发环境

文章目录 1.开发环境2.集成开发环境搭建2.1 安装Ros2.2 安装 Vs code2.3 安装vs code 插件 3.Vs code 配置ROS3.1 创建ROS工作空间3.2 从文件夹启动Vs code3.3 使用Vscode 编译ROS 空间3.4 使用Vs code 创建功能包 4.编写简单Demo实例4.1编写代码4.2编译与执行 1.开发环境 系统…

(文章复现)分布式电源选址定容的多目标优化算法

参考文献&#xff1a; [1]夏澍,周明,李庚银.分布式电源选址定容的多目标优化算法[J].电网技术,2011,35(09):115-121. [2] Ye Tian, Ran Cheng, Xingyi Zhang, and Yaochu Jin, “PlatEMO: A MATLAB platform for evolutionary multi-objective optimization [educational for…

毕设论文的分类号与UDC查询

对于毕业论文分类号与UDC&#xff0c;可以根据个人研究领域查询。 中图分类号查询链接&#xff1a; 中图分类号查询 | 中国图书馆分类法 | 中图法 | 中图分类号 (clcindex.com)https://www.clcindex.com/category/ UDC查询链接: UDC Summaryhttps://udcsummary.info/php/ind…

探秘计算机内部的魔法:模拟计算机内部的怎么使用门电路实现运算的奥秘

1.前言 在当今数字时代&#xff0c;我们享受着计算机带来的便利和效率&#xff0c;但很少有人意识到在计算机背后的神秘世界。计算机内部运算的奥秘并非仅仅是一系列简单的加减乘除&#xff0c;而是依托着深奥的门电路与位运算符展开的神秘舞蹈。在这篇博客中&#xff0c;我们…

Web3与社会契约:去中心化治理的新模式

在数字化时代&#xff0c;技术不断为我们提供新的可能性&#xff0c;而Web3技术作为一种基于区块链的创新&#xff0c;正在引领着互联网的下一波变革。它不仅改变了我们的经济模式和商业逻辑&#xff0c;还对社会契约和权力结构提出了全新的挑战和思考。本文将深入探讨Web3的基…

OpenAI宣布GPT-4-Turbo全面升级,GPT-4 Turbo 新增视觉理解能力,可同时处理文本和图像信息

OpenAI宣布GPT-4-Turbo全面升级&#xff0c;GPT-4 Turbo with Vision新增视觉理解能力&#xff0c;可同时处理文本和图像信息&#xff0c;极大简化了开发流程。 OpenAI宣布GPT-4 Turbo全面升级&#xff01;根据官方说法&#xff0c;这一波 GPT 的升级包括&#xff1a; 更长的上…