JAVA十大排序算法之桶排序详解
作者:阿粤Ayue 发布时间:2022-11-08 01:07:47
桶排序
桶排序是计数排序的升级,计数排序可以看成每个桶只存储相同元素,而桶排序每个桶存储一定范围的元素,通过函数的某种映射关系,将待排序数组中的元素映射到各个对应的桶中,对每个桶中的元素进行排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序),最后将非空桶中的元素逐个放入原序列中。
桶排序需要尽量保证元素分散均匀,否则当所有数据集中在同一个桶中时,桶排序失效。
代码实现
1.找出数组中的最大值max和最小值min,可以确定出数组所在范围min~max
2.根据数据范围确定桶的数量
1.若桶的数量太少,则桶排序失效
2.若桶的数量太多,则有的桶可能,没有数据造成空间浪费
所以桶的数量由我们自己来确定,但尽量让元素平均分布到每一个桶里,这里提供一个方式
(最大值 - 最小值)/每个桶所能放置多少个不同数值+1
3.确定桶的区间,一般是按照(最大值 - 最小值)/桶的数量来划分的,且左闭右开
public class BucketSort {
public static final int[] ARRAY = {35, 23, 48, 9, 16, 24, 5, 11, 32, 17};
/**
* @param bucketSize 作为每个桶所能放置多少个不同数值,即数值的类型
* 例如当BucketSize==5时,该桶可以存放{1,2,3,4,5}这几种数字,
* 但是容量不限,即可以存放100个3
*/
public static List<Integer> sort(List<Integer> array, int bucketSize) {
if (array == null || array.size() < 2)
return array;
int max = array.get(0), min = array.get(0);
// 找到最大值最小值
for (int i = 0; i < array.size(); i++) {
if (array.get(i) > max)
max = array.get(i);
if (array.get(i) < min)
min = array.get(i);
}
//获取桶的数量
int bucketCount = (max - min) / bucketSize + 1;
//构建桶,初始化
List<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketCount);
List<Integer> resultArr = new ArrayList<>();
for (int i = 0; i < bucketCount; i++) {
bucketArr.add(new ArrayList<>());
}
//将原数组的数据分配到桶中
for (int i = 0; i < array.size(); i++) {
//区间范围
bucketArr.get((array.get(i) - min) / bucketSize).add(array.get(i));
}
for (int i = 0; i < bucketCount; i++) {
if (bucketSize == 1) {
for (int j = 0; j < bucketArr.get(i).size(); j++)
resultArr.add(bucketArr.get(i).get(j));
} else {
if (bucketCount == 1)
bucketSize--;
//对桶中的数据再次用桶进行排序
List<Integer> temp = sort(bucketArr.get(i), bucketSize);
for (int j = 0; j < temp.size(); j++)
resultArr.add(temp.get(j));
}
}
return resultArr;
}
public static void print(List<Integer> array) {
for (int i : array) {
System.out.print(i + " ");
}
System.out.println("");
}
public static void main(String[] args) {
print(Arrays.stream(ARRAY).boxed().collect(Collectors.toList()));
System.out.println("============================================");
print(sort(Arrays.stream(ARRAY).boxed().collect(Collectors.toList()), 2));
}
}
时间复杂度
桶排序算法遍历了2次原始数组,运算量为2N,最后,遍历桶输出排序结果的运算量为N,初始化桶的运算量为M。
对桶进行排序,不同的排序算法算法复杂度不同,冒泡排序算法复杂度为O(N^2),堆排序、归并排序算法复杂度为O(NlogN),我们以排序算法复杂度为O(NlogN)进行计算,运算量为N/M * log(N/M) * M
最终的运算量为3N+M+N/M * log(N/M) * M,即3N+M+N(logN-logM),去掉系数,时间复杂度为O(N+M+N(logN-logM))
算法稳定性
桶排序算法在对每个桶进行排序时,若选择稳定的排序算法,则排序后,相同元素的位置不会发生改变,所以桶排序算法是一种稳定的排序算法。
来源:https://blog.csdn.net/weixin_43477531/article/details/119821587


猜你喜欢
- Android canvas drawBitmap方法详解及实例之前自己在自定义view,用到canvas.drawBitmap
- dart 是一个面向对象的语言;面向对象有继承封装多态dart的所有东西都是对象,所有的对象都是继承与object类一个类通常是由属性和方法
- 一、引入pom<?xml version="1.0" encoding="UTF-8"?>
- 这篇文章主要介绍了Java如何把int类型转换成byte,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的
- 一、背景项目中要解析xml,由于Dom4j的诸多优点,我就用Dom4j解析xml,代码如下:public void readXML() {
- 本文实例讲述了C#处理Access中事务的方法。分享给大家供大家参考。具体如下:Access不能像SQL server一样直接执行多条语句,
- [LeetCode] 3. Longest Substring Without Repeating Characters 最长无重复字符的子
- 前言传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop、事物,这么做有两个缺点:1、如果所有的内容都配置在.xml
- 本文实例为大家分享了Java实现简单日历界面的具体代码,供大家参考,具体内容如下请使用JFrame、JPanel、JButton、JLabe
- 创建自定义启动器0、项目总览1、创建项目,引入依赖创建项目 spring-boot-jdbc-starter,引入依赖,pom文件如下:&l
- 因为系统的菜单列表是不轻易改变的,所以不需要在每次请求的时候都去查询数据库,所以,在第一次根据用户id请求到菜单列表的时候,可以把菜单列表的
- Android的一个核心特性就是一个应用程序可作为其他应用程序中的元素,可为其他应用程序提供数据。例如,如果程序需要用某些控件来加载一些图片
- Unity中,我们怎么制作UI物体发光的渐隐渐现的效果呢?比如说我们有一张月亮光晕的精灵图片我们可以给它添加一个CanvasGroup组件我
- 一、什么是JSONJSON: JavaScript Object Notation JS对象简谱,是一种类似于XML的语言。相比于XML,它
- 过滤掉其他的播放器,使用我自己的播放器来做 wv.set
- 一、通过html页面打开Android本地的app1、首先在编写一个简单的html页面<html> &nb
- 介绍最近项目开发中用到了WebView播放视频的功能,总结了开发中犯过的错误,这些错误在开发是及容易遇到的,所以我这里总结了一下,希望大家看
- ELK环境安装ELK是指Elasticsearch、Kibana、Logstash这三种服务搭建的日志收集系统,具体搭建方式可以参考《Spr
- 导入redis的jar包<!-- redis --> <dependency>  
- Java数组声明、创建、初始化一维数组的声明方式:type var[]; 或type[] var;声明数组时不能指定其长度(数组中元素的个数