//位图排序法,时空高效的至高境界
/*
位图排序法有两个限制条件:
1、待排序数据都在一个已知的相对较小的范围内; 也不小?
2、所有数据没有重复;
*/
#include <stdio.h>
#define BITSPERWORD 32
#define SHIFT 5
#define MASK 0x1F
#define N 10000000
int a[1 + N/BITSPERWORD];
void set(int i){
a[i >> SHIFT] |= (1<<(i & MASK));
}
void clr(int i){
a[i >> SHIFT] &= ~(1<<(i & MASK));
}
int test(int i){
return a[i >> SHIFT] & (1<<(i & MASK));
}
int main(void)
{
int i, j;
for (i = 0; i < N; i++) {
clr(i);
}
//while (scanf("%d", &i) != EOF) {
// set(i);
//}
for (j = 0; j < 3; j++) { //供简单的正确性测试
scanf("%d", &i); //注意,输入的数不能重复
set(i); //否则当只输入一次
}
for (i = 0; i < N; i++) {
if (test(i))
printf("%d\n", i);
}
return 0;
}
http://www.cnblogs.com/Flouse/archive/2007/12/12/bitSort.html
为什么说这个算法时空效率达到及致呢?我们对100万个不重复的正整数(1000,0000以内)的文件进行测试:
系统排序 C++/STL.set C/qsort C/位图
总时间(s) 89 38 12.6 10.7
计算时间(s) 79 28 2.4 0.5
内存使用(MB) 0.8 70 4 1.25
(本测试数据是在较旧的电脑上测试的,但还是体现性能的差距)
第一行是总时间,第二行的计算时间是总时间减去数据读取耗时10.2秒。虽然通用C++程序使用内存和CPU时间是专用C程序(C/位图)的50倍,但是它的使用仅需要一半的代码,并能很容易扩展到其他问题上,这也是专用C程序最大的缺点吧。
下文回复还有网友提供的Bitmap排序的C#版,我还没有进行性能测试,估计性能也是很好的,而且那样的程序扩展性显然强很多,但是就失去了空间优势了。
凡事力求尽可能简洁,但不能简略。