基本思想
将待排序数组中的元素分散到若干个「桶」中,然后对每个桶中的元素再进行单独排序。
算法步骤
- 确定桶的数量:根据待排序数组的值域范围,将数组划分为 k 个桶,每个桶可以看做是一个范围区间。
- 分配元素:遍历待排序数组元素,将每个元素根据大小分配到对应的桶中。
- 对每个桶进行排序:对每个非空桶内的元素单独排序(使用插入排序、归并排序、快排排序等算法)。
- 合并桶内元素:将排好序的各个桶中的元素按照区间顺序依次合并起来,形成一个完整的有序数组。
以 [39,49,8,13,22,15,10,30,5,44] 为例,演示一下桶排序算法的整个步骤。
适用场景
数据分布均匀且范围明确,排序稳定性,高效内部排序算法可用,对稳定性有要求,特定类型数据排序;
对于数据分布不均或空间限制严格的场景,选择桶排序时需谨慎评估其适用性。
排序稳定性
桶排序的稳定性取决于桶内使用的排序算法。如果桶内使用稳定的排序算法(比如插入排序算法),并且在合并桶的过程中保持相等元素的相对顺序不变,则桶排序是一种 稳定排序算法。反之,则桶排序是一种 不稳定排序算法。
代码实现(golang)
func bucketSort(arr []float64, bucketSize int) []float64 {
if len(arr) == 0 {
return arr
}
minVal, maxVal := arr[0], arr[0]
for _, v := range arr {
if v < minVal {
minVal = v
}
if v > maxVal {
maxVal = v
}
}
bucketCount := int((maxVal-minVal)/float64(bucketSize)) + 1
buckets := make([][]float64, bucketCount)
for _, v := range arr {
index := int((v - minVal) / float64(bucketSize))
buckets[index] = append(buckets[index], v)
}
sortedArray := make([]float64, 0)
for _, bucket := range buckets {
if len(bucket) > 0 {
insertSort(bucket)
sortedArray = append(sortedArray, bucket...)
}
}
return sortedArray
}
func insertSort(arr []float64) {
for i := 1; i < len(arr); i++ {
temp := arr[i]
j := i - 1
for j >= 0 && arr[j] > temp {
arr[j+1] = arr[j]
j--
}
arr[j+1] = temp
}
}
func main() {
arr := []float64{0.897, 0.565, 0.656, 0.1234, 0.665, 0.3434}
sortedArr := bucketSort(arr, 5)
fmt.Println(sortedArr)
}