桶排序的工作原理是将数组分到有限数量的桶子里。每个桶子再个别排序 (有可能再使用别的排序算法或以递归方式继续使用桶排序进行排序)。桶排序利用了函数的映射关系,高效与否的关键在于这个映射函数的确定。为了使桶排序更加高效,我们需要做到以下两点:
- 在额外空间充足的情况下,尽量增大桶的数量;
- 使用的映射函数能够将输入的 N 个数据均匀的分配到 K 个桶中;
什么时候最快
当输入的数据可以均匀的分配到每一个桶中,桶排序的时间复杂度是 O(n)。
什么时候最慢
当输入的数据被分到了同一个桶中。
示意图
元素分布在桶中:
JavaScript代码实现
function bucketSort(arr, bucketSize) {if (arr.length === 0) return arr;let i;let minValue = arr[0]; // 将最小值初始化为数组的第一个元素let maxValue = arr[0]; // 将最大值初始化为数组的第一个元素for (i = 1; i < arr.length: i++) {if (arr[i] < minValue) {minValue = arr[i]; // 找出数据中的最小值} else if (arr[i] > maxValue) {maxValue = arr[i]; // 找出数据中的最大值}}// 桶的初始化const DEFAULT_BUCKET_SIZE = 5; // 设置桶的默认数量为 5bucketSize = bucketSize || DEFAULT_BUCKET_SIZE;const bucketCount = Math.floor((maxValue - minValue) / bucketSize) + 1;const buckets = new Array(bucketCount);for (i = 0; i < buckets.length; i++) {buckets[i] = [];}// 利用映射关系将数据分配到各个桶中for (i = 0; i < arr.length; i++) {buckets[Math.floor((arr[i] - minValue) / bucketSize)].push(arr[i]);}arr.length = 0;for (i = 0; i < buckets.length; i++) {insertionSort(buckets[i]);for (let j = 0; j < buckets[i].length; j++) {arr.push(buckets[i][j]);}}return arr;}
