数据结构与算法-排序(十)桶排序(Bucket Sort)
摘要
桶排序和基数排序类似,相当于基数排序的另外一种逻辑。它是将取值范围当做创建桶的数量,桶的长度就是序列的大小。通过处理比较元素的数值,把元素放在桶的特定位置,然后遍历桶,就可以得到有序的序列。
逻辑
创建一定数量的桶(数组或者链表)。制定规则将序列中的元素均匀地分布在不同的桶中。然后对每个桶内排序,最后合并非空的桶。
流程
- 创建一定数量的桶
- 元素均匀分布在桶中(根据规则来看)
- 桶内排序
- 合并非空的桶
下面还用无序的整数元素序列,将这个序列给排序有序。
实现
获取序列中的最大值,这里按照最大值有多少位,来确定外部循环多少次后得到有序的序列,也就是每一位都会循环遍历比较。
// 获取最大值
int max = array[0];
for (int i = 1; i < array.length; i++) {
if (max < array[i]) {
max = array[i];
}
}
桶排序实现方法
每一个整数的进制位是 0 到 9 这 10 个数,所以这里就创建10个桶,分别对应这10个数,每个桶的高度就是序列的长度。
下一步就是创建记录每个桶大小的数组,来放置元素个数,在取出桶中的元素时,就可以确定遍历的长度,减少遍历无用的空间。同时这是元素在桶中的索引位置。
// 桶数组
int[][] buckets = new int[10][array.length];
// 每个桶中的元素数量
int[] bucketSizes = new int[buckets.length];
接下来,就是根据最大值的进位数量,从个位进位开始对元素进行处理排序,bucketSizes 记录对应位置数值的数量,并提供给 buckets 数组在桶中的元素索引位置。
这里比较难理解一些,比如有 23和43 这两个数据,若从个位开始处理,因为个位都是 3,那么放在桶中的位置应该是 buckets[3][0]。如果是这样,23 会被后来的 43 覆盖。那么就用一个记录 3 数值出现次数的数组,即 bucketSizes[3],当存放 23 之后,bucketSizes[3] 加 1, 那么后面放 43 的时候,它的位置就是 buckets[3][1], 避免了覆盖。
当所有元素放置完成之后,就遍历 buckets 桶,依次取出元素,在遍历桶循环时,每个桶遍历的最大值就是 bucketSizes 中的数量,就不需要把桶的长度全部遍历完,减少遍历次数。
for (int divider = 1; divider <= max; divider *= 10) {
for (int i = 0; i < array.length; i++) {
int no = array[i] / divider % 10;
buckets[no][bucketSizes[no] ++] = array[i];
}
}
int index = 0;
for (int i = 0; i < buckets.length; i++) {
for (int j = 0; j < bucketSizes[i]; j++) {
array[index ++] = buckets[i][j];
}
bucketSizes[i] = 0;
}
时间和空间复杂度
- 时间复杂度:O(n + n * logn - n * logm)
- 空间复杂度:O(n+m)
- 属于稳定排序
m 是桶的数量
数据结构与算法-排序(十)桶排序(Bucket Sort)的更多相关文章
- JavaScript 数据结构与算法之美 - 桶排序、计数排序、基数排序
1. 前言 算法为王. 想学好前端,先练好内功,只有内功深厚者,前端之路才会走得更远. 笔者写的 JavaScript 数据结构与算法之美 系列用的语言是 JavaScript ,旨在入门数据结构与算 ...
- Hark的数据结构与算法练习之桶排序
算法说明 桶排序的逻辑其实特别好理解,它是一种纯粹的分而治之的排序方法. 举个例子简单说一下大家就知道精髓了. 假如对11,4,2,13,22,24,20 进行排序. 那么,我们将4和2放在一起,将1 ...
- 数据结构与算法之非比较排序【Java】
比较排序与非比较排序的对比 常见的快速排序.归并排序.堆排序.冒泡排序等属于比较排序.在排序的最终结果里,元素之间的次序依赖于它们之间的比较.每个数都必须和其他数进行比较,才能确定自己的位置.在冒泡排 ...
- 数据结构和算法(Golang实现)(25)排序算法-快速排序
快速排序 快速排序是一种分治策略的排序算法,是由英国计算机科学家Tony Hoare发明的, 该算法被发布在1961年的Communications of the ACM 国际计算机学会月刊. 注:A ...
- 数据结构和算法(Golang实现)(23)排序算法-归并排序
归并排序 归并排序是一种分治策略的排序算法.它是一种比较特殊的排序算法,通过递归地先使每个子序列有序,再将两个有序的序列进行合并成一个有序的序列. 归并排序首先由著名的现代计算机之父John_von_ ...
- 计数排序与桶排序(bucket sort)
Bucket Sort is a sorting method that subdivides the given data into various buckets depending on cer ...
- 数据结构和算法(Golang实现)(18)排序算法-前言
排序算法 人类的发展中,我们学会了计数,比如知道小明今天打猎的兔子的数量是多少.另外一方面,我们也需要判断,今天哪个人打猎打得多,我们需要比较. 所以,排序这个很自然的需求就出来了.比如小明打了5只兔 ...
- 数据结构和算法(Golang实现)(19)排序算法-冒泡排序
冒泡排序 冒泡排序是大多数人学的第一种排序算法,在面试中,也是问的最多的一种,有时候还要求手写排序代码,因为比较简单. 冒泡排序属于交换类的排序算法. 一.算法介绍 现在有一堆乱序的数,比如:5 9 ...
- 数据结构和算法(Golang实现)(20)排序算法-选择排序
选择排序 选择排序,一般我们指的是简单选择排序,也可以叫直接选择排序,它不像冒泡排序一样相邻地交换元素,而是通过选择最小的元素,每轮迭代只需交换一次.虽然交换次数比冒泡少很多,但效率和冒泡排序一样的糟 ...
- 数据结构和算法(Golang实现)(21)排序算法-插入排序
插入排序 插入排序,一般我们指的是简单插入排序,也可以叫直接插入排序.就是说,每次把一个数插到已经排好序的数列里面形成新的排好序的数列,以此反复. 插入排序属于插入类排序算法. 除了我以外,有些人打扑 ...
随机推荐
- 矩阵按对角线打印---python
将一个矩阵(二维数组)按对角线向右进行打印.(搜了一下发现好像是美团某次面试要求半小时手撕的题)Example:Input:[[1,2,3,4],[5,1,2,3],[9,5,1,2]]Output: ...
- ESP32使用SPIFFS文件系统笔记
基于ESP-IDF4.1 1 #include <stdio.h> 2 #include <string.h> 3 #include <sys/unistd.h> ...
- Sharding+SpringBoot+Mybatis 读写分离
基于Sharding JDBC的读写分离 1.引入pom.xml <dependencies> <!-- mybatis --> <dependency> < ...
- 「NOIP2017」宝藏
「NOIP2017」宝藏 题解 博客阅读效果更佳 又到了一年一度NOIPCSP-S 赛前复习做真题的时间 于是就遇上了这道题 首先观察数据范围 \(1 \le n \le 12\) ,那么极大可能性是 ...
- python 09篇 操作Excel
一.往Excel中写数据 使用pip install xlwt安装xlwt模块,用xlwt模块进行对Excel进行写数据. import xlwt # book = xlwt.Workbook() # ...
- Pandas高级教程之:稀疏数据结构
目录 简介 Spare data的例子 SparseArray SparseDtype Sparse的属性 Sparse的计算 SparseSeries 和 SparseDataFrame 简介 如果 ...
- groff编写man页
groff 是大多数 Unix 系统上所提供的流行的文本格式化工具 nroff/troff 的 GNU 版本.它一般用于编写手册页,即命令.编程接口等的在线文档.在本文中,我们将给你展示如何使用 gr ...
- Leetcode1.两数之和——简洁易懂
> 简洁易懂讲清原理,讲不清你来打我~ 输入一个数组和一个整数,从数组中找到两个元素和为这个整数,输出下标
PAT乙级:1056 组合数的和 (15分) 给定 N 个非 0 的个位数字,用其中任意 2 个数字都可以组合成 1 个 2 位的数字.要求所有可能组合出来的 2 位数字的和.例如给定 2.5.8,则 ...
- NOI2021游记
NOI2021游记 前言 写于 2021.7.28,成绩榜刚出后几个小时.总分 345 拿到银牌 183 名. 我的高中 OI 生活在这里画上句号.结局对我而言虽然不够完美,但是无论怎样都是我人生道路 ...