在之前的哈希表中,如果要在表中存放一个整数,此时就要申请一个整型的内存来存放它,一个整型数据在32位或64位平台下都占4个字节。如果现在需要存储的数据非常多,比如说40亿个不重复的数据,就需要160亿个字节来存储,1GB的内存表示的是10亿个字节,此时就需要16GB的内存来存放这些数据,而我们普通的电脑内存一般都是4G的内存,这显然是存放不下的。我们知道,内存中的最小单位是比特位。如果能用一个比特位来存放一个整型,只需要0.5GB的内存。
一个比特位可以表示一个0或1。如果要表示40亿个数据,可以申请0.5GB的内存。如果要存放的数据为10,就将第10个比特位设置为1。如果要查找的数据为100,就查看第100个比特位处的状态,如果为1说明,100存在于这堆数据中,如果为0说明不存在。
位图的概念
像上述所描述的,在一个结构中,用一个比特位来描述一个数据的状态,这种结构就称为位图。位图实际上是哈希表的一种变形。
1. 位图的结构定义
首先,该位图中最大能表示的比特位个数需要提前设定。
然后,根据最大比特位数来进行内存的申请。内存不能以比特位为单位进行申请,所以可以自己选用一种数据类型来申请内存,这里以64位8字节为一个数组元素长度进行内存的申请。
结构定义如下:
#include<stdint.h>//uint64_t需引用该头文件
//位图以uint64_t为单位进行内存的申请
typedef uint64_t BitMapType;
//指定位图最大能表示的数字范围
#define MAXSIZE 1000
//位图的结构定义
typedef struct BitMap
{
BitMapType* data;
uint64_t capacity;//位图中最大能表示的比特位个数
}BitMap;
2. 位图的初始化
初始化时要指定位图所能存储的最大比特位个数。然后根据该个数进行内存的申请。如果最大能表示的比特位为100,因为我们是以64位8字节(数组元素类型)为单位进行申请,此时需要2个数组元素的内存大小;如果最大比特位为300,此时需要5个数组元素的内存大小,所以,最大比特位capacity与64位的数组元素个数n之间满足:n = capacity/64 + 1;
在申请完内存之后,内存中存放的都是随机值,为方便后续的操作,将内存中的状态均置为0.