mirror of
https://github.com/krahets/hello-algo.git
synced 2024-12-27 13:56:29 +08:00
1.8 KiB
1.8 KiB
拓展到桶排序
如果我们把上述 bucket
中的每个索引想象成一个桶,那么可以将计数排序理解为把 n
个元素分配到对应的桶中,再根据桶与桶之间天然的有序性来实现排序。
以上解读便是「桶排序 Bucket Sort」的核心思想。具体地,桶排序考虑将 n
个元素根据大小范围均匀地分配到 k
个桶中,由于桶之间是有序的,因此仅需在每个桶内部执行排序,最终按照桶之间的大小关系将元素依次排列,即可得到排序结果。
假设使用「快速排序」来排序各个桶内的元素,每个桶内元素数量为 \frac{n}{k}
,则排序单个桶使用 O(\frac{n}{k} \log\frac{n}{k})
时间,排序所有桶使用 O(n \log\frac{n}{k})
时间。当桶数量 k
接近 n
时,时间复杂度则趋向于 $O(n)$ 。
(图)
理论上桶排序的时间复杂度是 O(n)
,但前提是需要将元素均匀分配到各个桶中,而这是不太容易做到的。假设我们要把淘宝中的 100
万件商品根据价格范围平均分配到 100
个桶中,由于商品价格不是均匀分布的,比如 1
~ 100
元的商品非常多、1
万元以上的商品非常少等,因此难以简单地设定各个桶的价格分界线。解决方案有:
- 先初步设置一个分界线,将元素分配完后,把元素较多的桶继续划分为多个桶,直至每个桶内元素数量合理为止;该做法一般使用递归实现;
- 如果我们提前知道商品价格的概率分布,则可以根据已知分布来设置每个桶的价格分界线;值得说明的是,数据分布不一定需要 case-by-case 地统计,有时可以采用一些常见分布来近似,例如自然界的正态分布;
(图)