【问题标题】:Radix Sort & O(N log N) Efficiency基数排序 & O(N log N) 效率
【发布时间】:2018-01-25 20:52:54
【问题描述】:

我最近一直在学习基数排序,我使用的资源之一是维基百科页面。目前关于算法的效率有以下段落:

基数排序相对于其他排序效率的话题 算法有些棘手,并且受制于很多 误解。基数排序是否同样有效,更少 比最好的基于比较的算法更有效或更有效 取决于所做假设的细节。基数排序复杂度 对于 n 个字长为 w 的整数的键是 O(wn)。有时 w 是 表示为常数,这将使基数排序更好(对于 n) 比最好的基于比较的排序足够大 算法,它们都执行 O(n log n) 比较来对 n 个键进行排序。 然而,通常 w 不能被认为是一个常数:如果所有 n 密钥是不同的,那么 w 必须至少为 log n 才能进行随机访问 机器能够将它们存储在内存中,这充其量是一个时间 复杂度 O(n log n)。 这似乎最多只能进行基数排序 与最好的基于比较的排序一样有效(如果 密钥比 log n 长得多)。

很遗憾,粗体部分变成了我无法通过的部分。我知道一般基数排序是 O(wn),并且通过其他来源已经看到如何实现 O(n),但不能完全理解为什么 n 个不同的键需要 O(n log n) 时间来随机存储 -访问机。我相当肯定它归结为一些简单的数学,但不幸的是,我仍然无法掌握扎实的理解。

我最接近的尝试如下:

给定一个基数“B”和该基数中的一个数字“N”,“N”可以有的最大位数是:

(logB of N) + 1.

如果给定列表中的每个数字 L 都是唯一的,那么我们有:

L *((logB of N) + 1) 个可能性

在这一点上我不确定如何进步。

是否有人能够以粗体扩展上述部分并分解为什么 n 个不同的键需要至少 log n 才能进行随机访问存储?

【问题讨论】:

    标签: sorting big-o radix-sort


    【解决方案1】:

    假设 MSB 基数排序使用常量 m bins:

    • 对于必须至少容纳n 不同值的任意大数据类型,所需的位数为N = ceiling(log2(n))
    • 因此存储每个值所需的内存量也是O(log n);假设顺序内存访问,读/写一个值的时间复杂度是O(N) = O(log n),虽然可以使用指针来代替
    • 位数为O(N / m) = O(log n)
    • 重要的是,每个连续数字必须相差 2 的幂,即m 也必须是 2 的幂;假设这对于硬件平台来说足够小,例如4 位数字 = 16 个 bin

    排序过程中:

    • 对于每个基数通行证,其中有O(log n)

      1. 计算每个桶:使用位操作获取当前数字的值 - O(1) 用于所有 n 值。应该注意,每个计数器也必须是N 位,尽管递增 1 将(摊销)O(1)。如果我们使用非 2 次幂数字,则通常为 O(log n log log n) (source)
      2. 使bucket count数组累积:必须执行m - 1加法,每一个都是O(N) = O(log n)(不同于增量特例)

      3. 写入输出数组:循环遍历n值,再次确定bin,并写入具有正确偏移量的指针

    因此总复杂度为O(log n) * [ n * O(1) + m * O(log n) + n * O(1) ] = O(n log n)

    【讨论】:

    • 感谢您的回答。关于第四点,这只是一般性评论吗?据我所知,基数排序不做任何比较
    • @Levenal 道歉,显然是My_Brain.exe has encountered a problem and has to close
    • 我可以建议重新启动 =) 编辑非常有帮助,谢谢。像你一样把它分解会让工作更容易。我还没有完全掌握,但现在更有信心到达那里。
    猜你喜欢
    • 2011-12-12
    • 1970-01-01
    • 2011-12-11
    • 2019-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多