位图的基本操作
位图的出现在一定程度上降低了内存使用。
应用场景:
当待处理数据超出内存处理范围时,将出现一系列的问题。此时,如果使用位图,就可以将内存的使用降至原使用内存大小的八分之一,极大程度的降低了内存不足所带来的诸多问题。
位图初始化:
1.判断输入参数的非法性;
2.初始化结构体变量。
代码:
void BitMapInit(BitMap* bm, uint64_t capacity){ //1.判断非法输入 if(bm == NULL){ //非法输入 return; } //2.初始化结构体变量 bm->capacity = capacity; uint64_t size = capacity/(8*sizeof(uint64_t))+ 1; //为结构体中的指针变量开辟空间 bm->data = (uint64_t*)malloc(size*sizeof(uint64_t)); //初始化 memset(bm->data,0,size); return; }
将某一位设置为1:
1.对输入参数的非法性进行判断;
2.获取index的下标与偏移量;
3.对相应值进行修改。
代码:
// 把第 index 位置为1 void BitMapSet1(BitMap* bm, uint64_t index){ if(bm == NULL || index>= BitMapMax){ //非法输入 return; } //获取index的下标与偏移量 uint64_t n;//下标 uint64_t offset;//偏移量 GetBitHashOff(bm,&n,&offset); //要想将每一位置为1,应进行按位或运算 bm->data[n] = bm->data[n] | (0x1ul<<offset); return; }
将某一位设置为0:
1.对输入参数的非法性进行判断;
2.获取index的下标与偏移量;
3.对相应值进行修改。
代码:
// 把第 index 位置为0 void BitMapSet0(BitMap* bm, uint64_t index){ if(bm == NULL || index>= BitMapMax){ //非法输入 return; } //获取index的下标与偏移量 uint64_t n;//下标 uint64_t offset;//偏移量 GetBitHashOff(bm,&n,&offset); //要想将每一位置为0,应进行按位与运算 bm->data[n] = bm->data[n] & ~(0x1ul<<offset); return; }
获取index的位图下标与偏移量:
1.求index的位图下标;
2.求index的位图偏移量。
代码:
void GetBitHashOff(BitMap* bm,uint64_t* n,uint64_t* offset){ //判断非法输入 if(bm == NULL){ return; } //判断下标 *n = bm->capacity/(8*sizeof(uint64_t)); //判断偏移量 *offset = bm->capacity%(8*sizeof(uint64_t)); return; }
将位图的全部位都设置为1:
1.对输入参数进行非法性判断;
2.对整个位图进行设置。
代码:
// 把整个位图所有的位都设为1. void BitMapFill(BitMap* bm){ if(bm == NULL){ //非法输入 return; } uint64_t size = bm->capacity/(8*sizeof(uint64_t))+1; memset(bm->data,0xff,size*sizeof(uint64_t)); return; }
位图的测试:
1.对index的位图下标与偏移量进行判断;
2.对位图中相应位置的值进行检测。
代码:
// 测试 index 为是 1 , 还是 0. 如果是1, 就返回1. 否则返回0. int BitMapTest(BitMap* bm, uint64_t index){ if(bm == NULL || index >=BitMapMax){ //非法输入 return 0; } uint64_t n; uint64_t offset; GetBitHashOff(bm,&n,&offset); int ret = bm->data[n]&(0x1ul<<offset); if(ret == 0){ return 0; }else{ return 1; } }
位图的查找:
1. 对位图中相应位置的值进行检测
代码:
//BitMap 元素查找 void BitMapPrint(BitMap* bm,int value,char* msg){ printf("\n******%s*******\n",msg); int i = 0; int size = bm->capacity/(8*sizeof(uint64_t))+1; for(;i<size;++i){ int j = 0; for(;j<sizeof(uint64_t)*8;++j){ if(bm->data[i]&(0x1ul<<j) ==value){ printf("[%d:%d:value] ",i,j); } } } printf("\n"); return; }
将位图的全部位都设置为0:
1.对输入参数进行非法性判断;
2.对整个位图进行设置。
代码:
// 把整个位图所有的位都设为0. void BitMapClear(BitMap* bm){ if(bm == NULL){ //非法输入 return; } uint64_t size = bm->capacity/(8*sizeof(uint64_t))+1; memset(bm->data,0x0,size*sizeof(uint64_t)); return; }
销毁位图:
1.对输入参数进行非法性检测;
2.释放已开辟空间。
代码:
void BitMapDestroy(BitMap* bm){ //1.判断非法输入 if(bm == NULL){ //非法输入 return; } //2.释放动态开辟空间 bm->capacity = 0; free(bm->data); bm->data = NULL; return; }