在研究“ BrainF ***的最快排序”时,我发现了该算法,它是O(N * k),其中k是输入中的最大值。它需要O(N)额外的存储空间。
从物理上讲,您有N堆令牌。堆栈的高度表示要排序的值。(每个令牌代表一点)。为另外N个堆栈留出空间。您从具有令牌的每个堆栈顶部取下一个令牌,然后从右到左向新集合中的每个堆栈添加一个,直到您的手为空。重复直到所有原始纸叠都为空。现在,新集合从左到右升序排列
在C中:
void sort(int A[], int N) { int *R = calloc(N,sizeof(int)); do { int i,count=0; for (i=0;i<N;i++) if A[i] { count++; A[i]--;} for (i=0;i<count;i++) R[i]++; } while (count); memcpy(A,R,N); //A is now sorted descending. free(R); }
这个算法有名字吗?它似乎类似于Bead Sort,但我认为它并不完全相同。
原来我一点也不懒。这是珠子排序。这是原始论文的定义(PDF链接):
考虑由 n个 正整数组成的集合 A。* 。。对于所有的 一个 在 甲 下降 一个 沿杆珠(每杆一个珠)中,从第一杆与起始 一个 “个杆。最后,从第 n 个层级到第一个层级逐级观察的珠子按升序表示 A。 __ ***
此实现以两种方式转换该算法:
y=x
以下是关于第一点的一些说明,直接从论文第二页的图表中可以得出:由于算法最初被实现,因此数组[3,2,4,2]将由一个网格表示,如下所示:
* * * * * * * * * * *
而让珠子掉落会产生:
然后,您必须从上至下读取行,以获取输出:[2,2,3,4]。而在按降序排列结果的版本中,您实际上是在这样做:
* * * * * * * * * * -> * * * * * * * * * * * *