Требуется: работа с бозе-хибардской сортировкой предпочтительно на языке C-like

Пожалуйста, укажите мне код для работы с реализацией Bose-Hibbard Sort, предпочтительно на языке C.

Я пытаюсь реализовать алгоритм в С#, но у меня нет копии алгоритма. Единственный образец, который у меня есть, - это реализация Fortran, которая является "бесплатным переводом" оригинальной версии Algol от Hibbard (из "Простой алгоритм сортировки" Journal of ACM vol 10 (1963) p142-50 - которого у меня нет), Версия Fortran кажется ошибкой (она делает ровно 1 сравнение и заканчивает выход, если они уже отсортированы), поэтому мой основной упор делается на то, чтобы получить рабочую версию для изучения.

Ответ 1

Из отсканированного PDF-документа оригинальная статья (скачанная из цифровой библиотеки ACM), OCR'd by copy'n'paste на Mac, а затем вручную очистить (довольно много):

procedure ternary sort (a, n); array a; integer n; begin integer j, L;
integer array x, y[0: log2(n-1)] ; integer procedure sum(w); array w;
begin integer j, s; s := 0; for j:= 0 step 1 until L do s := s+w[j]×2↑j; sum := s
end; procedure compare; begin real w;
if a[sum(x)] > a[sum(y)] then begin w := a[sum(x)]; a[sum(x)] := a[sum(y)];
a[sum(y)] := w end end;
L := entier log2(n-1); for j := 0 step 1 until L do begin x[j] := 0;
y[j] := if j = 0 then 1 else 0 end;
A: compare; j := 0;
C: go to if x[j] = y[j] = 0 then zero else if x[j] = y[j] = 1 then one else
if x[j] = 0 then first two else two;
zero: x[j] := y[j] := 1; if sum(y) ≤ n-1 then go to A;
one: y[j] := 0; go to A;
two: x[j] := 0; j := j+1; go to C;
first two: x[j] := y[j] := 0; if j = L then go to exit; j := j+1;
if y[j] = 1 then go to D; x[j] := y[j] := 1; if sum(y) > n-1 then
go to first two; if sum(y) < n-1 then j := 0;
D: x[j] := 0; y[j] := 1; go to A;
exit: end

В оригинале функции "log2" задаются как "log 2". Линия прерывается, как в оригинале. Это предшествует революции "структурированного программирования" - теперь вы можете понять, почему структурированное программирование - хорошая идея. Это также предшествует тщательной, четкой компоновке кода. Интересно видеть метки "два слова" и имена процедур. (В Пересмотренный отчет для Algol-60 (PDF или HTML), он говорит: типографические функции, такие как пустое пространство или изменение новой строки, не имеют никакого значения на эталонном языке. Однако они могут использоваться свободно для облегчения чтения. Это означает, что то, что кажется "двумя словами", в современных компьютерных языках - это всего лишь одно слово в Algol-60, поиск в Google показывает, что ключевые слова были отличены от переменных и т.д., подчеркнув или напечатав жирным шрифтом или заключенный в кавычки какого-то рода. Язык также использовал несколько символов, найденных на клавиатурах, три примера в этой программе: "×", "↑" и "≤".)

С помощью вложенных процедур вам понадобится довольно много "свободного перевода", чтобы закодировать это в Fortran.

Здесь он переформатирован - возможно, немного легче увидеть, что такое код; множество высказываний "идти" не облегчает понимание. Теперь вы можете понять, почему Дейкстра написал "GOTO считается вредным".

procedure ternary sort (a, n); array a; integer n; 
begin
    integer j, L;
    integer array x, y[0: log2(n-1)]; 
    integer procedure sum(w); array w;
    begin
        integer j, s; 
        s := 0; 
        for j:= 0 step 1 until L do s := s+w[j]×2↑j; 
        sum := s
    end;
    procedure compare;
    begin
        real w;
        if a[sum(x)] > a[sum(y)] then
        begin
            w := a[sum(x)]; 
            a[sum(x)] := a[sum(y)];
            a[sum(y)] := w 
        end 
    end;
    L := entier log2(n-1);
    for j := 0 step 1 until L do
    begin
        x[j] := 0;
        y[j] := if j = 0 then 1 else 0
    end;
A:  compare; j := 0;
C:  go to if x[j] = y[j] = 0 then zero
          else if x[j] = y[j] = 1 then one
          else if x[j] = 0 then first two 
          else two;
zero:
    x[j] := y[j] := 1;
    if sum(y) ≤ n-1 then go to A;
one:
    y[j] := 0; 
    go to A;
two:
    x[j] := 0; 
    j := j+1; 
    go to C;
first two:
    x[j] := y[j] := 0;
    if j = L then go to exit; 
    j := j+1;
    if y[j] = 1 then go to D; 
    x[j] := y[j] := 1; 
    if sum(y) > n-1 then go to first two; 
    if sum(y) < n-1 then j := 0;
D:  x[j] := 0;
    y[j] := 1; 
    go to A;
exit:
end