介绍
桶排序常被应用在数据规模一定,允许少量空间开销的情况下,假设待排序数组长度为m,待排序数据范围长度为n,则其时间复杂度为O(m+n),空间复杂度为O(m+n)
算法思想
桶排序通过统计每个元素前面元素的个数来进行排序。如一个元素e前面有6个元素,那么自身肯定排在第7位。
通过一个例子来说明:
假设有待排序数据:1,1,7,3,3,8,3,2,1,4,6,8,7
如下图所示:
1、用bitmap统计每个数字出现的次数,其实就是在数组对应数字下标处统计其出现次数,如1出现了3次,则在数组下标1出记录为3
2、统计排序后每个数字前面的数的个数,我们知道排序后0一定是在1前面,1一定是在2前面,因此在第一步统计完数组后,就知道2前面还有几个数,2前面数字的个数为0和1的个数,加上2本身有1个所以最终记录为4
3、从右至左扫描待排序数组,如扫描到7的时候,对应第2步统计的数组下标中,前面的数加上自身的数有9个,因此7应该存放到第9个位置,对应数组下标为9-1=8,同时将数组中7下标处的计数减一,最终得到排序后的序列
代码实现
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int arr[] = {1,1,7,3,3,8,3,2,1,4,6,8,7};
bucketSort(arr, 9);
System.out.println(Arrays.toString(arr));
}
public static void bucketSort(int arr[],int max){
int tempArr[] = Arrays.copyOf(arr, arr.length);
int count[] = new int[max];
//先统计每个数出现的次数
for (int i : arr) {
count[i]++;
}
//统计当前数字自身及前面的数字个数
for (int i = 1; i < count.length; i++) {
count[i] = count[i-1] + count[i];
}
//排序
for (int i = arr.length - 1; i >= 0; i--) {
arr[--count[tempArr[i]]] = tempArr[i];
}
}
}
输出结果:
[1, 1, 1, 2, 3, 3, 3, 4, 6, 7, 7, 8, 8]
总结
桶排序思路较为简单,适合应用在待排序数据大小范围较小的情况下。