web-dev-qa-db-ja.com

基数ソートの空間の複雑さがO(k + n)であるのはなぜですか?

最大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)

12
skr_robo

基数ソートのスペースの複雑さは、各基数のソートに使用するソートにバインドされています。最良の場合、それはソートを数えています。

ソートをカウントするために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の補助配列です。

基数ソートはカウントソートを使用するため、基数ソートのスペースの複雑さのカウントは、基数ソートのスペースの複雑さの下限です。

6
Jayson Boubin

用語の問題があると思います。 Jayson Boubinの回答 で言及されている質問の実装と実装のスペースの複雑さはO(n+k)です。ただし、kは最長の単語(または最長の数字)の長さではありません。 kは、「アルファベット」のサイズです。異なる数字(数字)または文字(単語)の数です。

buckets = [list() for _ in range( RADIX )]

このコードは、RADIX要素を持つ配列を作成します。この特定の実装では、RADIXは定数です(スペースの複雑さはO(n)です)が、一般的には変数です。 RADIXkであり、異なる桁数(アルファベットの文字)です。また、このknに依存せず、場合によってはnより大きくなる可能性があるため、スペースの複雑さは一般にO(n + k)です。

Editthis 実装では、placement(またはtmp)のサイズはO(k)kの定義を使用)。これは、klog(maxNumber)ベース10であり、placementサイズがlog(maxNumber)ベース256。しかし、これが一般的なケースかどうかはわかりません。

2
DAle

基数ソートは、データセット内の数値の各桁に対してカウントソートを使用します。カウントソートのスペースの複雑さはO(n + k)です。ここで、kはデータセット内の最大数です。

10進数の範囲は0〜9であるため、基数ソート(基数ソート内で使用されるソートをカウント)を使用して4つの10進数(11,22,88,99)をソートすると、各桁に対して、サイズb = 10の配列が作成されます。ベースです。

これは、使用される合計スペースが合計桁数*(n +基数)になることを意味します。合計桁数が一定の場合。空間の複雑さはO(n + base)になります。

したがって、基数ソートの空間の複雑さはO(n + b)です。

0
Muhammad Amsal