算法研究(二) bitmap在排序中的妙用
来源:互联网 发布:恒腾网络十大股东 编辑:程序博客网 时间:2024/05/09 12:10
题目:在一个文件中存放着几百万个非负整形数据,它们最大不超过7位,且无重复数据,现将该文件中的数据按升序进行排序。
对于排序,相信没人会陌生,已知的通用排序算法对于这个题目都显得有些力不从心,昂贵的内存开销(如果采用硬盘排序倒是可以减少内存开销,但时间上将耗费更多),巨大的时间耗费(这点是最不能接受的)。所谓的巧妙算法实际上都是分析问题的特点,针对它的特殊性而得出的。对于这个问题,有两个条件必须注意:一是数据非负且最大不超过7位;二是数据无重复。有了这两个条件,位图就可以派上用场了。
可以设置一个大小为1000万的位图,差不多相当于二十多万个整形的大小,它的每一位对应着一个最大不超过7位的数据,先清空该位图,然后从文件中读数据,将相应位置1。然后扫描位图,将非0位的对应数据输出到文件中去,整个过程便己完成,具体算法如下:
- #define SIZEBIT 10000000
- #define SIZE SIZEBIT/32 + 1
- void cleanAll(unsigned int* bitmap) {
- int i;
- for (i = 0; i < SIZE; ++i)
- bitmap =0;
- }
- void set(unsigned int* bitmap, unsigned int index) {
- bitmap[index/32] |= 1 << index%32;
- }
- void clean(unsigned int* bitmap, unsigned int index) {
- bitmap[index/32] &= ~(1 << index%32);
- }
- int get(unsigned int* bitmap, unsigned int index) {
- return bitmap[index/32] & (1 << index%32);
- }
- void sort() {
- unsigned int bitmap[SIZE];
- cleanAll(bitmap);
- FILE *fp = fopen("sortFile.txt", "r");
- unsigned int data;
- while (EOF != fscanf(fp, "%d", &data)) {
- set(bitmap, data);
- }
- fclose(fp);
- fp = fopen("sorted.txt", "w");
- int i;
- for (i = 0; i < SIZEBIT; ++i) {
- if (get(bitmap, i))
- fprintf(fp, "%d\n", i);
- }
- fclose(fp);
- }
实际上这种思想有点类似于哈希,只不过哈希算法简单的成了VALUE=KEY而已。如果条件中允许重复,我们就需要额外弄一个count数组用于计算重复数据。而如果数据没有几百万那么大,但它分部的很均匀,我们仍可以使用这种算法,可以将哈希桶的大小弄得小一点,以减小内存开销,不过我们恐怕还得花费额外的精力去处理哈希冲突,可以考虑使用链表,然后使用插入排序算法。而如果数据的分部不是那么均匀,而是存在着大量的局部收敛,那么哈希冲突所带来的巨大的时间耗费便不是我们可以接受的了,就应该考虑其它算法思想了。
参考文献
《编程珠玑》(美)本特利(Bentley,J.)- 算法研究(二) bitmap在排序中的妙用
- 算法研究(二) bitmap在排序中的妙用
- bitmap 在排序中的应用
- 异或算法在算法求解中的妙用
- 面试中的排序算法总结(二)
- JavaScript中的排序算法(二)
- UDF在层次型数据处理中的妙用之二
- 二进制在数学中的妙用(转帖)
- 深入剖析排序算法(二)------直接插入排序的研究及改进
- 搜索引擎算法研究(二)
- 排序算法(二)
- 排序算法(二)
- 排序算法(二)
- 排序算法 (二)
- 排序算法(二)
- DoEvents 在VB中的妙用
- 双引号在搜索中的妙用
- 二进制在数学中的妙用
- 宏定义中的 "#" 和 "##" 的区别
- touch命令
- 修改上传文件的名字
- Tomcat7.0的配置
- Linux下高性能网络编程中的几个TCP/IP选项
- 算法研究(二) bitmap在排序中的妙用
- 计算机操作系统实验之_进程观测_实验报告
- 防止MOS管击穿的措施
- Windows系统编程(一):内核对象
- 关于进程的一些小问题
- 深信服的笔试题
- epoll模型设计海量级连接服务器
- apache配置 错误 目录后面必须有/ 才能访问
- DFT IDFT FFT IFFT