桶排序的原理和计数排序类似,可以说是计数排序的升级版。他利用了函数映射关系,将输入的值映射到对应的桶里面去。
所以他的高效就在于这个映射函数的确定。所以需要做到如下两点:
1.在额外空间充足的情况下,尽量增大桶的数量。
2.使用映射函数能将输入的N个数据均匀的分配到K个桶中去。
此外就是对于桶中的数据元素的排序时,使用哪种比较排序的算法比较好,对性能的影响至关重要。
什么时候最快:
当输入数据可以均匀分配到每一个桶中去.
什么时候最慢:
当输入数据分配到一个桶中去.
参考代码:
使用的是插入排序。
public class BucketSort { public static void main(String[] args) { int [] a = {121, 39, 56, 20, 9, 7, 16}; System.out.println(Arrays.toString(bucketSort(a, 5))); } private static int[] bucketSort(int[] arr, int bucketSize) { //arr复制 int[] a = Arrays.copyOf(arr, arr.length); //寻找最大值和最小值 int max = a[0]; int min = a[0]; for(int i = 0; i < a.length; i ++){ if(a[i] > max){ max = a[i]; } else if(a[i] < min){ min = a[i]; } } //math.floor()对浮点数向下取整 int bucketCount = (int)Math.floor((max - min) / bucketSize) + 1; int [][] buckets = new int[bucketCount][0]; //通过映射函数将各数据映射到桶中去 for(int i = 0; i < a.length; i ++){ int index = (int)Math.floor((a[i] - min) / bucketSize); buckets[index] = arrApend(buckets[index], a[i]); } int arrIndex = 0; for(int[] bucket : buckets){ if(bucket.length <= 0){//招那些装了数据的桶 continue; } //对每个桶进行排序, 使用插入排序 bucket = insertSort(bucket); for(int value : bucket){ a[arrIndex ++] = value; } } return a; } private static int[] arrApend(int[] array, int value) { array = Arrays.copyOf(array, array.length + 1); array[array.length - 1] = value; return array; } //插入排序 -- 一个标志位 和之前的所有元素比较 private static int[] insertSort(int [] a){ int temp = 0; int j = 0; for(int i = 1; i < a.length; i ++){ temp = a[i]; for(j = i; j > 0 && a[j - 1] > temp; j --){ a[j] = a[j - 1]; } a[j] = temp; } return a; } }
结果截图:
以上就是这篇的内容,如果有什么错误或者可以改进的地方,亦或是你有什么疑惑,欢迎留言。让我们共同进步。谢谢!