持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第30天,点击查看活动详情
作者平台:
| CSDN:blog.csdn.net/qq_4115394…
| 知乎:www.zhihu.com/people/1024…
| GitHub:github.com/JiangXia-10…
| 微信公众号:1024笔记
本文一共1877字,预计阅读8分钟
前言
前面几篇文章介绍了一些比较经典的排序算法,比如冒泡排序、插入排序、选择排序、希尔排序、归并排序、堆排序以及速度较快的快速排序,其中稳定的排序算法有:冒泡排序、插入排序、归并排序,不稳定的排序算法有:选择排序、希尔排序、快速排序、堆排序,今天继续学习另一个比较常见的稳定的排序算法:桶排序算法。
什么是桶排序
桶排序是指首先将待排序的数组分到有限数量的桶里,然后在分别对每个桶里的元素进行排序 (对每个桶里的元素进行排序有可能是使用别的排序算法,也有可能是采用递归的方式继续使用桶排序进行排序)。桶排序是利用了函数的映射关系把数据分配到桶里,所以桶排序的效率如何跟桶的分配算法有很大的关系。
桶排序的步骤可以总结如下:
1、首先需要找出待排序数组numbers中的最大值maxValue;
2、根据最大值和最小值决定桶的数量:count=maxValue+1;
3、再次遍历原始待排序数组,得到原数组中存在的各个元素,以及出现的次数;
4、最后遍历桶数组,这里有两层循环,外层循环从桶的第一位开始(即下标为零);内层循环遍历桶数组中下标为i的值出现的次数,把排序好的元素放进输出数组
当桶内元素分布均匀时,桶排序的时间复杂度为 O(n)。但是当桶内元素分布极不均匀时时间复杂度为 O(nlogn),还会创建许多空桶,造成空间浪费。
桶排序的java实现
根据上述逻辑对于桶排序的java实现代码如下:
package com.jiangxia.SortDemo;
import java.util.Arrays;
public class BucketSort {
/**
* 桶排序具体实现
* @param numbers:待排序数组
*/
public static void bucketSort(int[] numbers) {
// 首先遍历原始待排序数组,找到数组中的最大值(或者最小值,具体根据需要的排序规则来,这里升序,所以是最大值)
int maxValue = numbers[0];
for (int i = 0; i < numbers.length; i++) {
if (numbers[i] > maxValue) {
maxValue = numbers[i];
}
}
// 创建一个桶数组,其下标为原始数组中最大值,该桶数组的下标代表元素,下标所对应的值则代表这个值出现的次数
int[] bucketArray = new int[maxValue + 1];
// 再次遍历原始待排序数组,得到原数组中存在的各个元素,以及出现的次数
for (int i = 0; i < numbers.length; i++) {
bucketArray[numbers[i]]++;
}
// 最后遍历桶数组,这里有两层循环,外层循环从桶的第一位开始(即下标为零);内层循环遍历桶数组中下标为i的值出现的次数
int index = 0;
for (int i = 0; i < bucketArray.length; i++) {
for (int j = 0; j < bucketArray[i]; j++) {
numbers[index++] = i;
}
}
}
/**
* 测试桶排序效果
* @param args
*/
public static void main(String[] args) {
//待排序数组
int[] numbers = {42, 13, 23, 51, 1, 0, 6, 94, 69, 99};
//输出排序之前的数组
System.out.println("桶排序之前:\n"+ Arrays.toString(numbers));
//堆待排序数组进行桶排序
bucketSort(numbers);
//输出排序之后的数组
System.out.println("桶排序之后 :\n"+Arrays.toString(numbers));
}
}
运行结果输出如下:
总结
桶排序的核心思想就是根据对待排序元素分配桶的过程,在可以确定需要排列的数组的范围时,可以生成该数值范围内有限个桶去对应数组中的数,然后将遍历的元素放入匹配的桶里,该过程可以看成是分类的过程,在分类完成后,只需要依次按照桶的顺序输出桶内存放的数值,这样就完成了桶排序。