Почему сортировка radix имеет пространственную сложность O (k + n)?

рассмотрим массив с n числа, имеющие максимум k цифры (см. правка). Рассмотрим программу сортировки radix из здесь:

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 в основном это 2d-список всех чисел. Однако, только n значения будут добавлены к нему. Почему сложность пространства равна O(k + n), а не O(n)? Поправьте меня, если я ошибаюсь, даже если мы рассмотрим пространство, используемое для извлечения цифр в определенном месте, оно использует только 1 (постоянную) память космос?

редактировать: я хотел бы объяснить мое понимание k. Предположим, я дам ввод [12, 13, 65, 32, 789, 1, 3], алгоритм, приведенный в ссылке, будет проходить через 4 прохода (первого while петли внутри функции). Вот!--2--> = 4, т. е. максимальное. цифр для любого элемента массива + 1. Таким образом, к нет. пропусков. Это то же самое k участвует во временной сложности этого алгоритма:O(kn) в этом есть смысл. Я не могу понять, как он играет роль в космической сложности: O(k + n).

3 ответов


сложность пространства сортировки Radix привязана к сортировке, используемой для сортировки каждого radix. В лучшем случае это Счетная сортировка.

вот псевдокод, предоставленный 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.

поскольку сортировка radix использует сортировку подсчета, пространство сортировки подсчета сложность-это нижняя граница пространственной сложности radix sort.


я думаю, что есть терминологическая проблема. Космическая сложность реализации и реализации вопроса, упомянутого в ответ Джейсона Бубена is O(n+k). Но!--1--> не является длиной самого длинного слова (или самого длинного числа). k - это размер "алфавита": количество разных цифр (в цифрах) или букв (в словах).

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

этот код создает массив с RADIX элементы. В этом частности реализация RADIX является константой(а сложность пространства O (n)), но в целом это переменная. RADIX это k количество различных цифр (букв в алфавите). И это k не зависит от n и может быть больше, чем n в некоторых случаях сложность пространства равна O (n+k) в целом.

редактировать: In этой внедрение размере placement (или tmp) составляет O(k) (С вашим определением k), потому что k is log(maxNumber) базовый 10 и placement размер log(maxNumber) базовый 256. Но я не уверен, что это общее дело.


сортировка Radix использует сортировку подсчета для каждой цифры чисел в наборе данных. Счетная сортировка имеет сложность пространства O (n+k), где k-наибольшее число в наборе данных.

десятичные цифры варьируются от 0 до 9, поэтому, если мы сортируем 4 десятичных числа (11,22,88,99), используя сортировку radix (подсчет сортировки, используемой в сортировке radix), для каждой цифры он создаст массив размера b = 10, где b является базой.

Это означает, что общее используемое пространство будет общим числом * (n + base). Если итого цифры постоянны. Сложность пространства становится O (N + base).

следовательно, сложность пространства сортировки Radix равна O (n+b).