基数排序的工作原理是选择一些以 b 为底的数字,将输入中的所有数字写入以 b 为底的数字,然后一次将数字排序一个数字。在这个答案中,我将重点介绍最低有效数字基数排序,其中我们按最低有效数字对所有内容进行排序,然后是第二低有效数字,等等。
每次我们按某个数字对数字进行排序时,我们必须做 O(n) 工作来将元素分布到所有桶中,然后 O(n + b) 工作来遍历桶并获得排序后的元素命令。因此,一轮基数排序的运行时间为 O(n + b)。
基数排序的轮数取决于每个数字的位数。如果你以 b 为底写数字,则数字 M 中将有 O(logb M) 个 base-b 数字。如果我们让 M 表示输入数组中的最大数字,则轮数基数排序将是 O(logb M)。因此,基数排序的渐近运行时间为
O(n + b) · O(logb M) = O((n + b) logb M)。
在典型的二进制基数排序中,您会选择 b = 2 并获得 O(n log M) 的运行时间。但是,您可以选择 b 为您想要的任何值。如果您选择较大的 b 值,则每个数字中以 b 为底的数字将更少(例如,先以 10 为基数,然后以 16 为基数;您通常需要更少的数字基数 16)。在你原来的问题中,你问
即使我们处理的数字最多只有 7 位数字,您是否仍需要循环至少 7 * 5 次?
答案是“不一定”。如果您使用 7 位数字进行 base-10 基数排序,那么是的,您必须循环 7 次。但是,如果您使用以 100 为底的基数排序,则只需循环 4 次。
您的另一个问题是关于使用 base-n 进行基数排序。如果我们选择我们使用的基数n,那么我们得到运行时是
O((n + n) logn M) = O(n logn M) = O(n log M / log n)
(这使用对数的变基公式来重写 logn M = log M / log n)。
这不是 O(n),你也不应该期望它是。这样想——基数排序的运行时间取决于被排序的字符串的长度。如果对少量极长的数字进行排序,运行时间必然大于对少量小数字进行排序的时间,因为您必须实际读取大数的数字。使用基数 n 的技巧只是一种渐近加速算法的技术。
希望这会有所帮助!