Skip to content

桶排序(Bucket Sort) ​

桶排序是一种非比较排序算法,适用于对均匀分布的数据进行排序。它将数据分配到一组桶中,每个桶再单独进行排序(通常使用其他排序算法,如插入排序),最后将桶中的元素合并起来得到最终的排序结果。桶排序的时间复杂度在特定条件下可以达到 $O(n + k)$,其中 $n$ 是待排序的元素个数,$k$ 是桶的数量。

1. 桶排序的基本概念 ​

桶排序的基本思想是:

  1. 确定桶的数量和范围: 将数据范围划分为若干个桶。
  2. 分配数据到桶中: 根据数据的值,将数据分配到相应的桶中。
  3. 对每个桶进行排序: 对每个桶内部的数据进行排序。
  4. 合并桶中的数据: 按顺序将桶中的数据合并成一个有序的输出数组。

2. 桶排序的算法步骤 ​

先根据最大值、最小值和数据范围确定桶的数量以及每个桶覆盖的区间;然后遍历数据,把每个元素放进对应的桶。桶内用插入排序这类稳定算法排好,最后按桶的顺序把数据合并到结果数组。

3. 桶排序的时间复杂度和空间复杂度 ​

  • 时间复杂度:

    • 最坏情况: $O(n^2)$,当桶内的排序算法(如插入排序)效率较低时,时间复杂度为 $O(n^2)$。
    • 最佳情况: $O(n + k)$,当数据均匀分布且桶内排序效率较高时,时间复杂度为 $O(n + k)$。
    • 平均情况: $O(n + k)$,时间复杂度通常为 $O(n + k)$。
  • 空间复杂度: $O(n + k)$,需要额外的空间存储桶和排序结果。

4. 桶排序的代码示例 ​

以下是使用 Go 语言实现的桶排序算法:

go
package main

import (
    "fmt"
    "sort"
)

// BucketSort 对整数切片进行桶排序
func BucketSort(arr []int) {
    if len(arr) == 0 {
        return
    }

    // 1. 找到数据的最小值和最大值
    minVal, maxVal := arr[0], arr[0]
    for _, v := range arr {
        if v < minVal {
            minVal = v
        }
        if v > maxVal {
            maxVal = v
        }
    }

    // 2. 确定桶的数量
    bucketCount := maxVal - minVal + 1
    buckets := make([][]int, bucketCount)

    // 3. 将数据分配到桶中
    for _, v := range arr {
        index := v - minVal
        buckets[index] = append(buckets[index], v)
    }

    // 4. 对每个桶进行排序并合并
    resultIndex := 0
    for _, bucket := range buckets {
        if len(bucket) > 0 {
            sort.Ints(bucket) // 使用 Go 内置的排序函数对桶内数据进行排序
            for _, v := range bucket {
                arr[resultIndex] = v
                resultIndex++
            }
        }
    }
}

func main() {
    arr := []int{29, 25, 3, 49, 9, 37, 21, 43}
    fmt.Println("Original array:", arr)
    BucketSort(arr)
    fmt.Println("Sorted array:", arr)
}

5. 桶排序的优缺点 ​

优点:

  • 数据均匀分布时,时间复杂度接近线性的 $O(n + k)$。
  • 值域较大的数据也能处理。

缺点:

  • 数据分布不均匀时表现不佳,时间复杂度可能退化到 $O(n^2)$。
  • 需要 $O(n + k)$ 的额外空间存储桶和排序结果。
  • 桶的数量和范围要选得合理,划分不当会拖慢排序。

总结 ​

桶排序不比较元素,靠值域划分桶来完成排序。数据均匀分布时是 $O(n + k)$,分布不均时退化到 $O(n^2)$,并且要付出 $O(n + k)$ 的额外空间。适合值域已知、分布大致均匀的数据。

参考资料 ​

同层页面 ​

相关页面 ​

Hello Golang