请指出工作Bose-Hibbard Sort实现的代码,最好是类似C语言。
我正在尝试在C#中实现该算法,但我没有该算法的副本。我唯一的样本是Fortran实现,它是Hibbard原始Algol版本的“免费翻译”(来自'一个简单的排序算法'期刊的ACM第10卷(1963)p142-50 - 我也没有) 。 Fortran版本似乎是错误的(它只进行1次比较,如果它们已经排序则最终退出)所以我主要关注的是获得一个工作版本来研究。
答案 0 :(得分:10)
从original article的扫描PDF(从ACM数字图书馆下载),在Mac上通过copy'n'paste进行OCR,然后手动清理(非常多):
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 '。换行符与原文相同。这种情况早于“结构化编程”革命 - 现在您可以看到为什么结构化编程是一个好主意。它也早于仔细,清晰的代码布局。看到“两个字”的标签和程序名称很有意思。 (在Revised Report for Algol-60(PDF或HTML)中,它说:诸如空格或更改为新行等印刷功能在参考语言中没有任何意义。但是,它们可能是这意味着现代计算机语言中的“两个单词”只是Algol-60中的一个单词;用Google搜索表明关键字与变量等区别在于加下划线或者用粗体或用引号括起来的。该语言还使用了键盘上通常找不到的一些符号;这个程序中的三个例子是'×','↑'和'≤'。)
使用嵌套程序,您需要进行大量“免费翻译”才能在Fortran中对此进行编码。
这里重新格式化 - 可能更容易看到代码是什么;过多的“转到”陈述并不容易理解。现在你可以看到为什么Dijkstra写了'GOTO Considered Harmful'。
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