桶排序
原理
桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。桶排序 (Bucket sort)的工作的原理:假设输入数据服从均匀分布,将数据分到有限数量的桶里,每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排)。
为了使桶排序更加高效,我们需要做到这两点:
- 在额外空间充足的情况下,尽量增大桶的数量
- 使用的映射函数能够将输入的 N 个数据均匀的分配到 K 个桶中
同时,对于桶中元素的排序,选择何种比较排序算法对于性能的影响至关重要。
算法的步骤
- 设置一个定量的数组当作空桶;
- 设置桶的区间范围(区间跨度=(最大值-最小值)/(桶的数量+1))
- 遍历输入数据,并且把数据一个一个放到对应的桶里去;
- 对每个不是空的桶进行排序;
- 从不是空的桶里把排好序的数据拼接起来。
画图解析
代码实现
public static void bucketSort(int[] arr){ if (arr.length==0) return; int minValue=arr[0]; int maxValue=arr[0]; for (int value:arr) { if (value<minValue) minValue=value; else if(value>maxValue) maxValue=value; } // int bucketNum=(maxValue-minValue)/arr.length+1; ArrayList<ArrayList<Integer>> bucket=new ArrayList<>(bucketNum); for (int i = 0; i <bucketNum ; i++) { bucket.add(new ArrayList<>()); } // for (int i=0;i<arr.length;i++){ int num=(arr[i]-minValue)/arr.length; bucket.get(num).add(arr[i]); } for (int i = 0; i <bucket.size() ; i++) { Collections.sort(bucket.get(i)); } int index=0; for (int i = 0; i <bucket.size() ; i++) { for (int j = 0; j <bucket.get(i).size() ; j++) { arr[index++]=bucket.get(i).get(j); } } } public static void main(String[] args) { int arr[]={4,4,6,5,3,2,8,1,9,3,5,6,7,12,23,34,21,22,14,19}; bucketSort(arr); System.out.println(Arrays.toString(arr)); }
性能分析
时间复杂度(平均) | 时间复杂度(最坏) | 时间复杂度(最好) | 空间复杂度 | 稳定性 |
O(n+k) | O(n^2) | O(n+k) | O(n+k) | 稳定 |