BS
说到排序,自然而然想到的都是冒泡排序、选择排序、快速排序、桶排序、堆排序…… 但是,你是否了解过珠排序呢?
珠排序( $Bead Sort$ )是一种时间复杂度为 $O(n)$ 的优秀算法,其基本概念来自于珠子。
如:给出一个数列[1,4,3,2],要将这个数列排列成从大到小的序列,其排列过程为:
[1,4,3,2]
[4,1,3,2]
[4,3,1,2]
[4,3,2,1]
- 首先,把需要排序的珠子放入
- 然后,因为引力原因,底下没有珠子的珠子会下坠,当然,计算机做不到像现实中的一列一列掉落,现实中能同时掉落所有珠子,所以现实中的时间复杂度为 $O(1)$
- 第2排珠子掉落后,第3、4排的珠子也会逐个掉落
- 所有珠子掉落完后就排列完了
C++代码:
#include <stdio.h>
#include <stdlib.h>
void bead_sort(int *a, int l)
{
int i, j, max, sum;
unsigned char *beads;
# define BEAD(i, j) beads[i * max + j]
for (i = 1, max = a[0]; i < l; i++)
if (a[i] > max) max = a[i];
beads =(unsigned char*)calloc(1, max * l);
for (i = 0; i < l; i++)
for (j = 0; j < a[i]; j++)
BEAD(i, j) = 1;
for (j = 0; j < max; j++) {
for (sum = i = 0; i < l; i++) {
sum += BEAD(i, j);
BEAD(i, j) = 0;
}
for (i = l - sum; i < l; i++) BEAD(i, j) = 1;
}
for (i = 0; i < l; i++) {
for (j = 0; j < max && BEAD(i, j); j++);
a[i] = j;
}
free(beads);
}
int main()
{
int i,n;
int l;
scanf("%d", &n);
int *x=new int[n];
for (i = 0; i < n; i++) scanf("%d", &x[i]);
l = n;
bead_sort(x, l);
for (i = 0; i < l; i++)
printf("%d ", x[i]);
delete x;
return 0;
}