当处理“The fastest sort for 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相似,但我认为它并不完全相同。
答案 0 :(得分:7)
事实证明我毕竟不是太懒。这是珠子排序。以下是original paper(PDF链接)的定义:
考虑一组 A n 正整数。 。 。 对于所有 a A 中的 a a 珠子(每根杆一根珠子),从第一根杆到 a '棒。最后,从 n 级到第一级逐级显示的珠子按升序表示 A 。
此实现以两种方式转换该算法:
y=x
线上工作的“框架”。这会更改结果,使每列中的“珠子”数表示按降序排序的输出。在原始算法中,每行中“珠子”的数量表示按升序排序的输出。以下是关于第一点的一些说明,直接来自论文第二页的图表:由于算法最初实现,数组[3,2,4,2]将由一个网格表示,如下所示:
* * *
* *
* * * *
* *
让珠子掉落产生:
* *
* *
* * *
* * * *
然后你必须从上到下读取行以获得输出:[2,2,3,4]。而在以降序显示结果的版本中,您实际上是这样做的:
* *
* * * *
* * * * -> * * * *
* * * * * * * *
答案 1 :(得分:0)
我知道Radix Sort是O(n * K)复杂度中的一个代表。