考虑一个n
个数字的数组,其数字最大为k
(请参阅编辑)。考虑来自here的基数排序程序:
def radixsort( aList ):
RADIX = 10
maxLength = False
tmp, placement = -1, 1
while not maxLength:
maxLength = True
# declare and initialize buckets
buckets = [list() for _ in range( RADIX )]
# split aList between lists
for i in aList:
tmp = i / placement
buckets[tmp % RADIX].append( i )
if maxLength and tmp > 0:
maxLength = False
# empty lists into aList array
a = 0
for b in range( RADIX ):
buck = buckets[b]
for i in buck:
aList[a] = i
a += 1
# move to next digit
placement *= RADIX
buckets
基本上是所有数字的第二个列表。但是,只会向其添加n
个值。为什么空间复杂度是O(k + n)而不是O(n)?如果我错了,请纠正我,即使我们考虑用于在特定位置提取数字的空间,它只使用1(常量)内存空间?
修改:我想解释一下我对k
的理解。假设我输入[12, 13, 65, 32, 789, 1, 3]
,链接中给出的算法将经历4次传递(函数内的第一个while
循环)。这里k
= 4,即最大数量。数组中任何元素的数字+ 1.因此k为否。通行证这与此算法的时间复杂度相同k
:O(kn)
这是有道理的。我无法理解它在空间复杂性中的作用:O(k + n)
。
答案 0 :(得分:6)
Radix sort的空间复杂度与它用于对每个基数进行排序的排序绑定。在最好的情况下,这是排序。
以下是CLRS提供的用于计算排序的伪代码:
Counting-sort(A,B,k)
let C[0..k] be a new array
for i = 0 to k
C[i] = o
for j = 1 to A.length
C[A[j]] = C[A[j]] + 1
for i = 1 to k
C[i] = C[i] + C[i-1]
for j = A.length down to 1
B[C[A[j]]] = A[j]
C[A[j]] = C[A[j]] - 1
如您所见,计数排序会创建多个数组,一个基于K的大小,另一个基于N的大小.B是输出数组,大小为n。 C是大小为k的辅助数组。
因为基数排序使用计数排序,计算排序的空间复杂度是基数排序空间复杂度的下限。
答案 1 :(得分:2)
我认为存在术语问题。 Jayson Boubin's answer中提到的问题实施和实施的空间复杂性为O(n+k)
。但k
不是最长单词(或最长数字)的长度。 k
是'字母'的大小:不同数字(以数字表示)或字母(以字为单位)的数字。
buckets = [list() for _ in range( RADIX )]
此代码创建一个包含RADIX
元素的数组。在这个特定的实现中,RADIX
是一个常量(并且空间复杂度是O(n)),但一般来说,它是一个变量。 RADIX
是k
,不同数字的数字(字母表中的字母)。此k
不依赖于n
,并且在某些情况下可能大于n
,因此空间复杂度通常为O(n + k)。
修改:在this实施中,placement
(或tmp
)的尺寸为O(k)
(定义为k
}),因为k
是log(maxNumber)
基础10
,而placement
大小是log(maxNumber)
基础256
。但我不确定这是一般情况。
答案 2 :(得分:0)
基数排序对数据集中每个数字位数使用计数排序。计数排序的空间复杂度为O(n + k),其中k是数据集中的最大数。
十进制数字的范围从0到9,所以如果我们使用基数排序(在基数排序中使用的计数排序)对4个十进制数字(11,22,88,99)进行排序,对于每个数字,它将创建大小为b =的数组10其中b是基础。
这意味着使用的总空间将是总数*(n +基数)。如果总数是常数。空间复杂度变为O(n + base)。
因此,Radix Sort的空间复杂度为O(n + b)。