最大n
桁のk
番号を持つ配列を考えてみます(編集を参照)。 ここ からの基数ソートプログラムを考えてみましょう:
_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
は基本的に、すべての数値の2次元リストです。ただし、n
値のみが追加されます。なぜ空間の複雑さはO(n)ではなくO(k + n)なのですか?私が間違っている場合は訂正してください。特定の場所で数字を抽出するために使用されるスペースを考慮しても、1つの(一定の)メモリスペースしか使用していませんか?
編集:k
についての私の理解を説明したいと思います。 _[12, 13, 65, 32, 789, 1, 3]
_の入力を与えるとすると、リンクで与えられたアルゴリズムは4つのパスを通過します(関数内の最初のwhile
ループの)。ここでk
= 4、つまり最大数配列内の任意の要素の桁数+1。したがって、kはnoです。パスの。これは、このアルゴリズムの時間計算量に関係するk
と同じです:O(kn)
これは理にかなっています。それが空間の複雑さにおいてどのように役割を果たすのか理解できません:O(k + n)
。
基数ソートのスペースの複雑さは、各基数のソートに使用するソートにバインドされています。最良の場合、それはソートを数えています。
ソートをカウントするために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
ご覧のとおり、ソートをカウントすると、1つはKのサイズに基づいて、もう1つはNのサイズに基づいて複数の配列が作成されます。Bはサイズnの出力配列です。 Cはサイズkの補助配列です。
基数ソートはカウントソートを使用するため、基数ソートのスペースの複雑さのカウントは、基数ソートのスペースの複雑さの下限です。
用語の問題があると思います。 Jayson Boubinの回答 で言及されている質問の実装と実装のスペースの複雑さはO(n+k)
です。ただし、k
は最長の単語(または最長の数字)の長さではありません。 k
は、「アルファベット」のサイズです。異なる数字(数字)または文字(単語)の数です。
buckets = [list() for _ in range( RADIX )]
このコードは、RADIX
要素を持つ配列を作成します。この特定の実装では、RADIX
は定数です(スペースの複雑さはO(n)です)が、一般的には変数です。 RADIX
はk
であり、異なる桁数(アルファベットの文字)です。また、このk
はn
に依存せず、場合によってはn
より大きくなる可能性があるため、スペースの複雑さは一般にO(n + k)です。
Edit: this 実装では、placement
(またはtmp
)のサイズはO(k)
(k
の定義を使用)。これは、k
がlog(maxNumber)
ベース10
であり、placement
サイズがlog(maxNumber)
ベース256
。しかし、これが一般的なケースかどうかはわかりません。
基数ソートは、データセット内の数値の各桁に対してカウントソートを使用します。カウントソートのスペースの複雑さはO(n + k)です。ここで、kはデータセット内の最大数です。
10進数の範囲は0〜9であるため、基数ソート(基数ソート内で使用されるソートをカウント)を使用して4つの10進数(11,22,88,99)をソートすると、各桁に対して、サイズb = 10の配列が作成されます。ベースです。
これは、使用される合計スペースが合計桁数*(n +基数)になることを意味します。合計桁数が一定の場合。空間の複雑さはO(n + base)になります。
したがって、基数ソートの空間の複雑さはO(n + b)です。