一.算法思想
一句话总结为:划分多个范围相同的子区间,每个子区间自排序,最后合并即可。
桶排序每个桶内存储一定范围的元素,通过映射函数,将待排序数组中的元素映射到各个元素分别对应的桶中,对每个桶中的元素进行排序,最后将非空桶中的元素逐个放入原序列中即可。桶排序需要尽量保证元素分散均匀,否则当所有数据集中在同一个桶中时,桶排序失效。
桶排序 (Bucket sort):工作原理是将待排序序列分到有限数量的桶里。每个桶再做个别排序。
二.时间复杂度
待排序序列大小为 N ,共分为 M 个桶:
- N 次循环,将每个元素装入对应的桶中
- M 次循环,对每个桶中的数据进行排序(平均每个桶有 N/M 个元素)
整个桶排序的时间复杂度为:
O( N ) + O( M∗( N/M ∗ log( N/M )))
当 N = M 时,复杂度为 O(N)
总结:
一般使用较为快速的排序算法,排序时间复杂度为 O( NlogN ),因此桶排序最好情况下的时间复杂度为线性时间 O( N ) 。桶排序的时间复杂度,取决于对各个桶内的数据进行排序的时间复杂度,因为其它部分的时间复杂度都为 O( N )。很显然,桶划分的范围越小,每个桶之间的数据会越少,排序所用的时间也会越少,但相应的空间消耗就会增大。
桶排序的最优时间复杂度为O( N ),最差时间复杂度取决于桶内数据的排序算法,所以桶的数量越多,时间效率越高,完美情况是每个桶中只有一个数据,时间复杂度可以达到O( N ),但是会浪费很大的空间,考虑时间和空间的权衡问题,在数据规模合适的情况下,桶排序的表现可以优于快排等基于比较的排序算法。
三.图解
(图片来源于网络)
四.代码实现
1.需要两个数组:
- 待排序数组 int[ ] arr = new int[ ]{4,3,6,3,5,1};
- 计数数组 int[ ] help = new int[max - min + 1]; //该数组大小为待排序数组中的最大值减最小值+1
1.求出待排序数组中的最大