Re: сортировка с линейной сложностью

From
Dmitriy K. ()
To
Ilya Teterin
Date
2002-07-31T18:20:48Z
Area
RU.ALGORITHMS
From: "Dmitriy K." <krylov@mail.primorye.ru>

Привет, Ilya!
Wed, 31 Jul 2002 10:17:30 +0000 (UTC) Вы написали :

 IT> Хай, Олл!

 IT> Существует ли алгоритм сортировки с линейной вычислительной
 IT> сложностью, если известно, что сортируемые данные - случайная
 IT> величина с равномерным распределением?

Существует. Но человечеству пока не известна ;-)

Зависит от того, что за "данные" и что за "величина".

Если величина - из некоторого конечного множества - например, 0-255, то
сортировку  последовательности с линейной скоростью a0, a1, ..., ak можно
сделать так:

1) посчитать, сколько раз встречается 0, сколько - 1 и т.д. Это можно
сделать за один проход последовательности, заведя 256 счетчиков.

2) построить отсортированную последовательность: сначала идут '0' - столько
раз, сколько встречались в исходной последовательности, затем '1' и т.д.
Линейность всё равно сохраниться, т.к. количество проходов равно k.

Вот так:

const k = 10;

var
  a: array[1..k] of byte;

procedure sort;
var
  counters: array[byte] of byte;
  i, j, l: byte;
begin
  FillChar(counters, SizeOf(counters), 0);
  for i := 1 to k do Inc(counters[a[k]]); // Шаг 1
  l = 1; // Шаг 2
  for i := 0 to 255 do
    for j := 1 to counters[a[i]] do
    begin
      a[l] := i;
      Inc(l);
    end;
end;

Как называется эта сортировка - я не помню. Кажется, "карманная".

Если же твоя "случайная величина" не помещается в границы байта, то тут надо
смотреть...

Например:
1) Если гарантировано все элементы разные - можно через битовые массивы
(правда, памяти пожрет...). Если встречается не больше k раз - через k
битовых массивов. Кстати, подойдет и для байтов, тогда вообще проще: в
Pascal уже есть подходящий битовый массив - производные от типа set.

2) Если не байт, а, например, слово (2 байта) - та же фигня, но на счетчики
больше памяти будет угрохано. На самом деле не так уж и важно, какое
представление. Просто для целых чисел получается проще - порядок задается
порядком счетчиков, тогда как для дробных приходится извращаться на шаге 2
да и память, память...

3) Сдается мне, что если эта "случайная величина" представляется, ну, для
простоты типом integer (32-х битным), то сначала нуна отсортировать по
младшим байтам (сохраняя информацию об оставшихся), потом - по более старшим
и т.д... Тогда для счетчиков нужно будет меньше памяти. Думать надо.

P.S. А может, сразу отсортированную последовательность генерить?

P.P.S. В инете проскакивала как-то информация о O(log(log(log(n))))
сортировке... Типа, для больших n ;) . Могу поискать на винте.

Удачи!
__________________________________________________________________________
--{ Dmitriy Krylov aka "Abulafia"   }-------------------------------------
--{ mailto: krylov@mail.primorye.ru }-------------------------------------



-- 
Отправлено через сервер Форумы@mail.ru - http://talk.mail.ru
--- ifmail v.2.15dev5
 * Origin: Talk.Mail.Ru (2:5020/400)