我想探索我对桶排序的分析,如下所示。
桶排序有多种实现方式。其中一些如下。
类型 1:
如果我们知道要排序的元素的范围,我们可以为每个可能的元素设置桶,然后将元素扔到它们对应的桶中。然后我们按顺序清空桶,结果是一个排序列表。在实现这个算法时,我们可以很容易地使用一个数组来表示我们的桶,其中每个数组索引处的值将代表相应桶中元素的数量。如果我们有 [0..max] 范围内的整数,那么我们设置一个 (max + 1) 个整数数组并将所有值初始化为零。然后我们依次遍历未排序的数组,读取每个元素的值,转到 buckets 数组中的相应索引,并在那里增加值。
时间:O(N)
空间:O(1)
类型 2:
示例:按年龄对一组人进行排序
年龄与用于排序的任意整数有些不同。因此,它的范围很小 [0-150](所有人的年龄都在 0 到 150 之间)。所以最快的排序方法是分配151个链表(我们称它们为桶)并根据每个人的年龄将每个人的数据结构放入桶中:
时间:O(N+K)
空间:O(N+K)
类型 3(类型 2 的变体,如维基百科所示)
函数 nextSort 是一个排序函数,用于对每个桶进行排序。如果使用的插入排序比最差的将是 O(n^2) 或将使用合并排序,以便我可以保持比 O(nlgn) 的稳定性。
- 问题:
1>如何认为是线性排序,是因为Type 1还是Type 2?
2>如果我使用像 WIkepedia 这样的类型 3,哪种排序对每个桶进行有效排序?
我知道在实践中使用插入排序的原因是我们希望桶很小,而对于小列表,插入排序比其他任何方法都快得多。即使在实现合并排序或快速排序时,当列表变得足够小时(比如低于 20 项左右)时,也会使用插入排序。
3>对于类型 3,我可以在什么基础上决定存储桶的范围?
这很重要,因为如果您尝试使用大量存储桶(例如远大于 n)进行存储桶排序,则运行时可能会受到扫描所有存储桶以查找您实际使用的存储桶所需的时间的支配,即使其中大部分是空的。
我做了分析基于:
维基百科
桶排序的复杂性怎么可能是O(n + k)?
算法设计与分析 1996 年 1 月 23 日讲义
http://www1bpt.bridgeport.edu/~dichter/lilly/bucketsort.htm
http://cs.nyu.edu/courses/fall02/V22.0310-002/ Lectures/lecture-23.html
如果我们使用链表实现桶,桶排序的复杂度是 O(n+k)?
桶排序的最坏情况复杂度是多少?