8.4 桶排序
算法实现
def bucket_sort(A, num_buckets=None):
"""
桶排序算法实现(假设输入元素在[0, 1)区间内均匀分布)
参数:
A: 输入数组,假设元素在[0, 1)区间内
num_buckets: 桶的数量,默认为len(A)
返回:
排序后的数组
"""
if not A:
return A
n = len(A)
if num_buckets is None:
num_buckets = n
# 步骤1: 创建桶
buckets = [[] for _ in range(num_buckets)]
# 步骤2: 将元素分配到桶中
for num in A:
# 计算元素应该放入哪个桶
bucket_index = int(num * num_buckets)
# 处理边界情况:当num = 1.0时
if bucket_index == num_buckets:
bucket_index = num_buckets - 1
buckets[bucket_index].append(num)
# 步骤3: 对每个桶内的元素进行排序
for bucket in buckets:
# 可以使用任何排序算法,这里使用插入排序(对小数组效率高)
insertion_sort(bucket)
# 也可以使用Python内置排序:
# bucket.sort()
# 步骤4: 按顺序合并所有桶
result = []
for bucket in buckets:
result.extend(bucket)
return result
def insertion_sort(arr):
"""
插入排序实现(用于桶内排序)
"""
for i in range(1, len(arr)):
key = arr[i]
j = i - 1
while j >= 0 and arr[j] > key:
arr[j + 1] = arr[j]
j -= 1
arr[j + 1] = key
# 更通用的桶排序实现(适用于任意范围的整数)
def bucket_sort_integers(A, num_buckets=None):
"""
适用于整数的桶排序
参数:
A: 输入整数数组
num_buckets: 桶的数量
返回:
排序后的数组
"""
if not A:
return A
n = len(A)
if num_buckets is None:
num_buckets = n
# 找到最大值和最小值
min_val = min(A)
max_val = max(A)
# 处理所有元素相等的特殊情况
if min_val == max_val:
return A[:]
# 创建桶
buckets = [[] for _ in range(num_buckets)]
# 将元素分配到桶中
range_val = max_val - min_val
for num in A:
# 计算元素应该放入哪个桶
bucket_index = int((num - min_val) * (num_buckets - 1) / range_val)
buckets[bucket_index].append(num)
# 对每个桶内的元素进行排序
for bucket in buckets:
insertion_sort(bucket)
# 按顺序合并所有桶
result = []
for bucket in buckets:
result.extend(bucket)
return result
运行时间分析
桶排序的总运行时间由三部分组成:分配元素到桶的时间、对每个桶内元素排序的时间、以及合并结果的时间。设 $ n_i $ 表示第 $ i $ 个桶中的元素个数,$ k $ 表示桶的数量,则总运行时间为:
T(n)=Θ(n)+∑i=0k−1O(ni2)+Θ(k) T(n) = \Theta(n) + \sum_{i=0}^{k-1} O(n_i^2) + \Theta(k) T(n)=Θ(n)+i=0∑k−1O(ni2)+Θ(k)
其中:
- $ \Theta(n) $:分配 $ n $ 个元素到桶的时间
- $ \sum O(n_i^2) $:对每个桶使用插入排序的时间(插入排序对 $ m $ 个元素耗时 $ O(m^2) $)
- $ \Theta(k) $:创建 $ k $ 个桶和合并结果的时间
通常选择 $ k = n $(桶数等于元素数),因此:
T(n)=Θ(n)+∑i=0n−1O(ni2)
T(n) = \Theta(n) + \sum_{i=0}^{n-1} O(n_i^2)
T(n)=Θ(n)+i=0∑n−1O(ni2)
最坏情况分析
当所有元素都落入同一个桶时(如输入已排序且分布不均),有:
- $ n_0 = n $,其余 $ n_i = 0 $
- $ \sum_{i=0}^{n-1} O(n_i^2) = O(n^2) $
因此最坏时间复杂度为:
T(n)=Θ(n)+O(n2)=O(n2)
T(n) = \Theta(n) + O(n^2) = O(n^2)
T(n)=Θ(n)+O(n2)=O(n2)
平均情况分析(输入在 [0,1)[0,1)[0,1) 均匀分布)
假设每个元素独立且等概率地落入 $ n $ 个桶中的任意一个,求期望运行时间 $ E[T(n)] $:
E[T(n)]=Θ(n)+O(∑i=0n−1E[ni2]) E[T(n)] = \Theta(n) + O\left( \sum_{i=0}^{n-1} E[n_i^2] \right) E[T(n)]=Θ(n)+O(i=0∑n−1E[ni2])
定义指示器随机变量:
Xij={1若 A[j] 落入桶 i0否则
X_{ij} = \begin{cases}
1 & \text{若 } A[j] \text{ 落入桶 } i \\
0 & \text{否则}
\end{cases}
Xij={10若 A[j] 落入桶 i否则
则:
ni=∑j=1nXij
n_i = \sum_{j=1}^n X_{ij}
ni=j=1∑nXij
计算 $ E[n_i^2] $:
E[ni2]=E[(∑j=1nXij)2]=E[∑j=1nXij2+∑1≤j≠k≤nXijXik]
E[n_i^2] = E\left[ \left( \sum_{j=1}^n X_{ij} \right)^2 \right] = E\left[ \sum_{j=1}^n X_{ij}^2 + \sum_{1 \leq j \neq k \leq n} X_{ij} X_{ik} \right]
E[ni2]=E(j=1∑nXij)2=Ej=1∑nXij2+1≤j=k≤n∑XijXik
利用期望的线性性:
=∑j=1nE[Xij2]+∑1≤j≠k≤nE[XijXik]
= \sum_{j=1}^n E[X_{ij}^2] + \sum_{1 \leq j \neq k \leq n} E[X_{ij} X_{ik}]
=j=1∑nE[Xij2]+1≤j=k≤n∑E[XijXik]
由于 $ X_{ij} $ 是指示器变量,$ X_{ij}^2 = X_{ij} $,且 $ E[X_{ij}] = \frac{1}{n} $,所以:
E[Xij2]=1n
E[X_{ij}^2] = \frac{1}{n}
E[Xij2]=n1
当 $ j \neq k $ 时,$ X_{ij} $ 与 $ X_{ik} $ 独立,因此:
E[XijXik]=E[Xij]⋅E[Xik]=1n⋅1n=1n2
E[X_{ij} X_{ik}] = E[X_{ij}] \cdot E[X_{ik}] = \frac{1}{n} \cdot \frac{1}{n} = \frac{1}{n^2}
E[XijXik]=E[Xij]⋅E[Xik]=n1⋅n1=n21
代入得:
E[ni2]=∑j=1n1n+∑1≤j≠k≤n1n2=n⋅1n+n(n−1)⋅1n2=1+n−1n=2−1n
E[n_i^2] = \sum_{j=1}^n \frac{1}{n} + \sum_{1 \leq j \neq k \leq n} \frac{1}{n^2} = n \cdot \frac{1}{n} + n(n-1) \cdot \frac{1}{n^2} = 1 + \frac{n-1}{n} = 2 - \frac{1}{n}
E[ni2]=j=1∑nn1+1≤j=k≤n∑n21=n⋅n1+n(n−1)⋅n21=1+nn−1=2−n1
对所有 $ i $ 求和:
∑i=0n−1E[ni2]=∑i=0n−1(2−1n)=n(2−1n)=2n−1
\sum_{i=0}^{n-1} E[n_i^2] = \sum_{i=0}^{n-1} \left(2 - \frac{1}{n}\right) = n \left(2 - \frac{1}{n}\right) = 2n - 1
i=0∑n−1E[ni2]=i=0∑n−1(2−n1)=n(2−n1)=2n−1
因此期望运行时间为:
E[T(n)]=Θ(n)+O(2n−1)=Θ(n)+O(n)=Θ(n)
E[T(n)] = \Theta(n) + O(2n - 1) = \Theta(n) + O(n) = \Theta(n)
E[T(n)]=Θ(n)+O(2n−1)=Θ(n)+O(n)=Θ(n)
更一般的线性时间条件
即使输入不服从均匀分布,只要满足:
∑i=0k−1ni2=O(n)
\sum_{i=0}^{k-1} n_i^2 = O(n)
i=0∑k−1ni2=O(n)
即所有桶的大小平方和与 $ n $ 呈线性关系,则桶排序的期望时间仍为 $ \Theta(n) $。这一条件比均匀分布更宽松,适用于许多实际场景。
结论
- 最坏情况时间复杂度:$ O(n^2) $
- 平均情况时间复杂度(均匀分布):$ \Theta(n) $
- 空间复杂度:$ \Theta(n) $
- 稳定性:是(若桶内排序算法稳定)
535

被折叠的 条评论
为什么被折叠?



