此算法也称为重力排序,它是从自然现象中汲取灵感的,设计时要牢记物体(或珠子)在重力作用下掉落。
想法:正数由一组像算盘上的珠子表示。
- 就像上面的图像一样,小珠从上到下表示以下数字:7,2,1,4,2。现在,假设这是时间t = 0时小珠的位置,每经过一秒,小珠就会如果它们下面没有珠子,则跌落一级。在这种情况下,它们只是停留在它们下面的珠子上。(杆从左到右编号,水平从下到下编号为1、2,…………n。)
- 现在,在时间t = 1时,从左起的前两个杆中的底部2个珠子停留在它们的位置,而从第二个杆的顶部开始的第二个珠子下降一个高度,停在其下面的珠子上。在第2级的第3和第4杆中的珠子下降到第1级。同时,在第3至7杆中的珠子下降了一级。现在,从上到下的数字变为:2、6、2、2、4。
- 这一直持续到时间t = 4 ,在这里我们得到了从上到下的数字排序序列,即:1、2、2、4、7。
为什么这样称呼呢?
当人们尝试可视化此算法时,似乎珠子在重力的影响下掉落到最底层,它们可以到达,导致这组珠子从下到上以降序排列。如果您无法形象地查看此链接,请访问此链接
假设我们必须对数字3、4、1、2进行排序。以上算法将像这样工作。
下面是代码,请在查看代码之前尝试自己实施。
编码:
// C++ program to implement gravity/bead sort
#include
using namespace std;
#define BEAD(i, j) beads[i * max + j]
// function to perform the above algorithm
void beadSort(int *a, int len)
{
// Find the maximum element
int max = a[0];
for (int i = 1; i < len; i++)
if (a[i] > max)
max = a[i];
// allocating memory
unsigned char beads[max*len];
memset(beads, 0, sizeof(beads));
// mark the beads
for (int i = 0; i < len; i++)
for (int j = 0; j < a[i]; j++)
BEAD(i, j) = 1;
for (int j = 0; j < max; j++)
{
// count how many beads are on each post
int sum = 0;
for (int i=0; i < len; i++)
{
sum += BEAD(i, j);
BEAD(i, j) = 0;
}
// Move beads down
for (int i = len - sum; i < len; i++)
BEAD(i, j) = 1;
}
// Put sorted values in array using beads
for (int i = 0; i < len; i++)
{
int j;
for (j = 0; j < max && BEAD(i, j); j++);
a[i] = j;
}
}
// driver function to test the algorithm
int main()
{
int a[] = {5, 3, 1, 7, 4, 1, 1, 20};
int len = sizeof(a)/sizeof(a[0]);
beadSort(a, len);
for (int i = 0; i < len; i++)
printf("%d ", a[i]);
return 0;
}
输出:
1 1 1 3 4 5 7 20
时间复杂度:
该算法的运行时复杂度范围从O(1)到O(S)(S是输入整数的总和),具体取决于用户的角度。最后,提出了三种可能的实现方式。
- O(1) :将所有珠子作为一个(同时)操作放在一起。这种复杂性无法在实践中实现。
- O( ):在使用重力的真实物理模型中,让珠子掉落所需的时间与最大高度的平方根成正比,最大平方根与n成正比。
- O(n) :由于不同的行数等于n,因此将帧中的一排珠子(代表一个数字)丢弃是一种独特的操作。
- O(S) :将每个珠子作为单独的操作放下,因为S是所有珠子的总和。
像鸽子洞排序一样,珠排序也很不寻常,因为在最坏的情况下它的执行速度可能比O( ),在最坏的情况下进行比较排序时可能会获得最快的性能。这是可能的,因为珠子排序的键始终是正整数,并且珠子排序会利用其结构。
空间复杂性:珠子分类是废物的记录保持者。额外内存的成本超过了存储阵列本身的成本。其内存复杂度为O( )
参考:
- https://www.wikiwand.com/cn/Bead_sort
- https://kukuruku.co/post/bead-sort/
- https://rosettacode.org/wiki/排序算法/ Bead_sort
- https://www.cs.auckland.ac.nz/~mjd/misc/BeadSort5.pdf