在所有具有效能优化的资料结构中,我想大家使用最多的就是 hash 表,是的,在具有定位查询上具有 O(1) 的常量时间,多么的简洁优美,
但是在特定的场合下:
①:对 10 亿个不重复的整数进行排序。
②:找出 10 亿个数字中重复的数字。
当然我只有普通的站群服务器,就算 2G 的内存吧,在这种场景下,我们该如何更好的挑选资料结构和演算法呢?
 
一:问题分析
这年头,大牛们写的排序演算法也就那么几个,首先我们算下放在内存中要多少 G: (10 亿 * 32)/(1024*1024*1024*8)=3.6G,可怜
的 2G 内存直接爆掉,所以各种神马的资料结构都玩不起来了,当然使用外排序还是可以解决问题的,由于要走 IO 所以暂时剔除,因为我们
要玩高效能,无望后我们想想可不可以在二进位制位上做些手脚?
比如我要对 {1,5,7,2} 这四个 byte 型别的数字做排序,该怎么做呢?我们知道 byte 是占 8 个 bit 位,其实我们可以将阵列中的值作为 bit 位的
key,value 用”0,1“来标识该 key 是否出现过?下面看图:

从图中我们精彩的看到,我们的阵列值都已经作为 byte 中的 key 了,最后我只要遍历对应的 bit 位是否为 1 就可以了,那么自然就成有序阵列了。
可能有人说,我增加一个 13 怎么办?很简单,一个位元组可以存放 8 个数,那我只要两个 byte 就可以解决问题了。

可以看出我将一个线性的阵列变成了一个 bit 位的二维矩阵,最终我们需要的空间仅仅是:3.6G/32=0.1G 即可,要注意的是 bitmap 排序不
是 N 的,而是取决于待排序阵列中的最大值,在实际应用上关系也不大,比如我开 10 个执行绪去读 byte 阵列,那么复杂度为:O(Max/10) 。
 
二:程式码
我想 bitmap 的思想大家都清楚了,这一次又让我们见证了二进位制的魅力,当然这些移位都是位运算的工作了,熟悉了你就玩转了。
1:Clear 方法(将阵列的所有 bit 位置 0)
比如要将当前 4 对应的 bit 位置 0 的话,只需要 1 左移 4 位取反与 B[0] & 即可。

1 #region 初始化所用的 bit 位为 0
2 ///

3 /// 初始化所用的 bit 位为 0
4 ///

5 /// 6 static void Clear(byte i)
7 {
8 //相当于 i%8 的功能
9 var shift = i & 0x07;
10
11 //计算应该放阵列的下标
12 var arrindex = i >> 3;
13
14 //则将当前 byte 中的指定 bit 位取 0,& 后其他对方阵列 bit 位必然不变,这就是 1 的妙用
15 var bitPos = ~(1 << shift); 16 17 //将阵列中的指定 bit 位置一 “& 操作” 18 a[arrindex] &= (byte)(bitPos); 19 } 20 #endregion   2:Add 方法(将 bit 置 1 操作) 同样也很简单,要将当前 4 对应的 bit 位置 1 的话,只需要 1 左移 4 位与 B[0] | 即可。 1 #region 设定相应 bit 位上为 1 2 ///

3 /// 设定相应 bit 位上为 1
4 ///

5 /// 6 static void Add(byte i)
7 {
8 //相当于 i%8 的功能
9 var shift = i & 0x07;
10
11 //计算应该放阵列的下标
12 var arrindex = i >> 3;
13
14 //将 byte 中的 1 移动到 i 位
15 var bitPos = 1 << shift; 16 17 //将阵列中的指定 bit 位置一 “| 操作” 18 a[arrindex] |= (byte)bitPos; 19 } 20 #endregion   2:Contain 方法(判断当前 bit 位是否是 1) 如果看懂了 Clear 和 Add,我相信最后一个方法已经不成问题了。 1 #region 判断当前的 x 在阵列的位中是否存在 2 ///

3 ///判断当前的 x 在阵列的位中是否存在
4 ///

5 /// 6 ///
7 static bool Contain(byte i)
8 {
9 var j = a[i >> 3] & (1 << (i & 0x07)); 10 11 if (j == 0) 12 return false; 13 return true; 14 } 15 #endregion 最后上总的程式码: View Code         文章来自互联网博客网站 http://www.cnblogs.com/huangxincheng/archive/2012/12/06/2804756.html