我最近一直在学习Radix排序,我使用的其中一个来源是维基百科页面。目前有关于算法效率的以下段落:
与其他排序相比,基数排序效率的主题 算法有点棘手,并且受到相当多的限制 误解。基数排序是否同样有效,更少 比最佳的基于比较的算法更有效或更有效 取决于所做假设的细节。基数排序复杂性 对于n个键是O(wn),它是字大小w的整数。有时w是 作为常数呈现,这将使基数排序更好(对于 n)比最好的基于比较的排序足够大 算法,它们都执行O(n log n)比较以排序n个键。 但是,通常w不能被视为常数: 如果全部为n 密钥是不同的,那么w必须至少为log n以进行随机访问 机器能够将它们存储在内存中,这样可以充分利用时间 复杂度O(n log n)。 这似乎最多可以进行基数排序 与最佳的基于比较的排序同样有效(如果是,则更糟 密钥比log n更长。
粗体的部分令人遗憾地变成了一个我无法通过的障碍。我知道一般来说Radix排序是O(wn),并且通过其他来源已经看到如何实现O(n),但是不能完全理解为什么n个不同的密钥需要O(n log n)时间来随机存储 - 访问机器。我相当肯定它归结为一些简单的数学,但不幸的是,一个坚实的理解仍然是我无法掌握的。
我最接近的尝试如下:
给定一个基数,'B'和该基数中的数字'N','N'的最大数字可以是:
(N的logB)+ 1。
如果给定列表中的每个数字L都是唯一的,那么我们最多可以:
L *((log的N)+ 1)可能性
此时我不确定如何进步。
是否有人能够以粗体扩展上述部分并分解为什么n个不同的密钥需要最少的log n用于随机存取存储?
答案 0 :(得分:0)
假设MSB基数排序为常量m
二进制位:
n
个不同值的任意大数据类型,所需的位数为N = ceiling(log2(n))
O(log n)
;假设顺序内存访问,读/写值的时间复杂度为O(N) = O(log n)
,尽管可以使用指针O(N / m) = O(log n)
m
也必须是2的幂;假设这对于HW平台来说足够小,例如4位数字= 16个容器在排序期间:
对于每个基数传递,其中有O(log n)
:
O(1)
获取所有n
值。应注意,每个计数器也必须是N
位,尽管增量为1将是(摊销)O(1)
。如果我们使用了非2位数,那么通常为O(log n log log n)
(source)使存储桶计数数组累积:必须执行m - 1
个添加,每个都是O(N) = O(log n)
(与增量特殊情况不同)
写出输出数组:循环通过n
值,再次确定bin,并用正确的偏移量写入指针
因此总复杂度为O(log n) * [ n * O(1) + m * O(log n) + n * O(1) ]
= O(n log n)
。