桶排序的工作原理是将数组分到有限数量的桶子里。每个桶子再个别排序 (有可能再使用别的排序算法或以递归方式继续使用桶排序进行排序)。桶排序利用了函数的映射关系,高效与否的关键在于这个映射函数的确定。为了使桶排序更加高效,我们需要做到以下两点:

  1. 在额外空间充足的情况下,尽量增大桶的数量;
  2. 使用的映射函数能够将输入的 N 个数据均匀的分配到 K 个桶中;

什么时候最快

当输入的数据可以均匀的分配到每一个桶中,桶排序的时间复杂度是 O(n)。

什么时候最慢

当输入的数据被分到了同一个桶中。

示意图

元素分布在桶中:
Bucket_sort_1.svg_.png

然后,元素在每个桶中排序:
Bucket_sort_2.svg_.png

image.pngJavaScript代码实现

  1. function bucketSort(arr, bucketSize) {
  2. if (arr.length === 0) return arr;
  3. let i;
  4. let minValue = arr[0]; // 将最小值初始化为数组的第一个元素
  5. let maxValue = arr[0]; // 将最大值初始化为数组的第一个元素
  6. for (i = 1; i < arr.length: i++) {
  7. if (arr[i] < minValue) {
  8. minValue = arr[i]; // 找出数据中的最小值
  9. } else if (arr[i] > maxValue) {
  10. maxValue = arr[i]; // 找出数据中的最大值
  11. }
  12. }
  13. // 桶的初始化
  14. const DEFAULT_BUCKET_SIZE = 5; // 设置桶的默认数量为 5
  15. bucketSize = bucketSize || DEFAULT_BUCKET_SIZE;
  16. const bucketCount = Math.floor((maxValue - minValue) / bucketSize) + 1;
  17. const buckets = new Array(bucketCount);
  18. for (i = 0; i < buckets.length; i++) {
  19. buckets[i] = [];
  20. }
  21. // 利用映射关系将数据分配到各个桶中
  22. for (i = 0; i < arr.length; i++) {
  23. buckets[Math.floor((arr[i] - minValue) / bucketSize)].push(arr[i]);
  24. }
  25. arr.length = 0;
  26. for (i = 0; i < buckets.length; i++) {
  27. insertionSort(buckets[i]);
  28. for (let j = 0; j < buckets[i].length; j++) {
  29. arr.push(buckets[i][j]);
  30. }
  31. }
  32. return arr;
  33. }