桶排序原理是将序列划分成k个单独的序列,然后再调用别的排序排序后再合并的一种排序办法
算法思路:
1、对数组中最大值和最小值之间进行区间切分,每个区间放入到对应的桶中
2、对每个桶进行排序(自选排序办法),然后合并
举例子:
比如序列 [ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ], 我们假设分配大小为3的桶。
入桶规则为对于第i个元素进入第 “ (第i个元素的值 - 最小元素值 ) / 桶大小” 个桶
第一步:我们可以将原序列划分并入桶转化为 [ [ 2, 1, 0 ], [ 5, 4, 3 ], [ 8, 7, 6 ], [ 9 ] ], 这里面包含了4个桶(数组)
第二步:我们对每个桶排序[ [ 0, 1, 2 ], [ 3, 4, 5 ], [ 6, 7, 8 ], [ 9 ] ]
第三步:我们出桶输出得到序列[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
完毕
代码
**
function BucketSort(nums, bucketSize = 3) {if (!nums.length === 0) return nums;let i, minValue = maxValue = nums[0];for (i = 1; i < nums.length; i++) { // 求得取值范围minValue = Math.min(minValue, nums[i])maxValue = Math.max(maxValue, nums[i])}let bucketCount = Math.floor((maxValue - minValue) / bucketSize) + 1; // 计算的到桶数量let buckets = new Array(bucketCount).fill('').map(() => []); // 建桶for (i = 0; i < nums.length; i++) {buckets[Math.floor((nums[i] - minValue) / bucketSize)].push(nums[i]); // 入桶}let pos = 0for (const bucket of buckets) {QuickSort(bucket); // 快排while(bucket.length){nums[pos++] = bucket.shift() 输出}}return nums;}
时间复杂度与划分的桶的大小有关系。
假如桶大小与原序列一样大,这里就和快排的时间复杂度一样了O(nlog(n))
假如桶的大小为1,那么这里就变成了计数排序 O(n + k) 其中k=(max(nums) - min(nums))
空间复杂度O(n + k) **
