哈希表拓展——位图

  • 位图的基本概念

位图 就是bitmap的缩写,是用每一位来存放数的状态的结构,适用于大规模的数据。

  • 位图的用处

位图主要用于海量数据处理,索引,数据压缩等方面。

  • 位图的结构

位图的结构类似于哈希表,位图就是用每一位的0或1来表示一个数的状态。

例如,我们现在有一个文件,这个文件中有数字1,3,5.我们就可以把第1位、第3位、第5位的状态设置为1,其余位为0。

                        

  • 位图的基本操作
bitmap.h:
#pragma once 
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<stddef.h>
#include<inttypes.h>
typedef uint64_t BitmapType;
typedef struct Bitmap{
    BitmapType* data;
    BitmapType capacity;
}Bitmap;

void BitmapInit(Bitmap* bm,uint64_t capacity);//初始化
void BitmapDestroy(Bitmap* bm);//销毁
void BitmapSet(Bitmap* bm,uint64_t index);//将某一位置为1
void BitmapUnset(Bitmap* bm,uint64_t index);//将某一位置为0
void BitmapFill(Bitmap* bm);//将所有位都置为1
void BitmapClear(Bitmap* bm);//将所有位都置为0
int BitmapTest(Bitmap* bm,BitmapType index);//测试
void GetOffSet(uint64_t index,uint64_t* n,uint64_t* offset);//测试函数的辅助函数
bitmap.c:
#include"bitmap.h"

void BitmapInit(Bitmap* bm,uint64_t capacity){
    if(bm == NULL)
        return;
    bm->capacity = capacity;
    BitmapType size = capacity/(sizeof(bm->data[0])*8)+1;
    bm->data = (BitmapType*)malloc(sizeof(BitmapType)*size);
    memset(bm->data,0,sizeof(BitmapType)*size);
    return;
}

void BitmapDestroy(Bitmap* bm){
    if(bm == NULL)
        return;
    bm->capacity = 0;
    free(bm->data);
    return;
}

void GetOffSet(uint64_t index,uint64_t* n,uint64_t* offset){
    if(n == NULL || offset == NULL)
        return;
    *n = index / (sizeof(BitmapType)*8);
    *offset = index % (sizeof(BitmapType)*8);
    return;
}

int BitmapTest(Bitmap* bm,BitmapType index){
    if(bm == NULL )
        return 0;
    if(index >= bm->capacity)
        return 0;
    uint64_t n,offset;
    GetOffSet(index,&n,&offset);
    uint64_t ret = bm->data[n] & (0x1ul << offset);
    return ret > 0 ? 1 : 0;
}

void BitmapSet(Bitmap* bm,uint64_t index){
    if(bm == NULL)
        return;
    if(index >= bm->capacity)
        return;
    uint64_t n,offset;
    GetOffSet(index,&n,&offset);
    bm->data[n] |= (0x1ul << offset);
    return;
}

void BitmapUnset(Bitmap* bm,uint64_t index){
    if(bm == NULL)
        return;
    if(index >= bm->capacity)
        return;
    uint64_t n,offset;
    GetOffSet(index,&n,&offset);
    bm->data[n] &= ~(0x1ul << offset);
    return;
}


void BitmapFill(Bitmap* bm){
    if(bm == NULL)
        return;
    BitmapType size = bm->capacity/(sizeof(bm->data[0])*8)+1;
    memset(bm->data,0xff,sizeof(BitmapType)*size);
}

void BitmapClear(Bitmap* bm){
    if(bm == NULL)
        return;
    BitmapType size = bm->capacity/(sizeof(bm->data[0])*8)+1;
    memset(bm->data,0x0,sizeof(BitmapType)*size);
}
test.c:
#include"bitmap.h"
#define PRINT_HEAD printf("\n============%s============\n",__FUNCTION__);

void TestInit(){
    PRINT_HEAD;
    Bitmap bm;
    BitmapInit(&bm,100);
    printf("capacity ecpect 100,actual %lu\n",bm.capacity);
    printf("data expect 0,actual %lu\n",bm.data[0]);
}

void TestDestroy(){
    PRINT_HEAD;
    Bitmap bm;
    BitmapInit(&bm,100);
    BitmapDestroy(&bm);
    printf("capacity ecpect 0,actual %lu\n",bm.capacity);
    printf("data expect NULL,actual %p\n",bm.data[0]);
}

void TestSet(){
    PRINT_HEAD;
    Bitmap bm;
    BitmapInit(&bm,100);
    BitmapSet(&bm,50);
    uint64_t  ret =  BitmapTest(&bm,50);
    printf("ret expect 1,actual %lu\n",ret);
    ret =  BitmapTest(&bm,10);
    printf("ret expect 0,actual %lu\n",ret);
}

void TestUnset(){
    PRINT_HEAD;
    Bitmap bm;
    BitmapInit(&bm,100);
    BitmapSet(&bm,50);
    uint64_t  ret =  BitmapTest(&bm,50);
    printf("ret expect 1,actual %lu\n",ret);
    BitmapUnset(&bm,50);
    ret =  BitmapTest(&bm,50);
    printf("ret expect 0,actual %lu\n",ret);
}

void TestFill(){
    PRINT_HEAD;
    Bitmap bm;
    BitmapInit(&bm,100);
    BitmapFill(&bm);
    uint64_t  ret =  BitmapTest(&bm,50);
    printf("ret expect 1,actual %lu\n",ret);
    ret =  BitmapTest(&bm,0);
    printf("ret expect 1,actual %lu\n",ret);
    ret = BitmapTest(&bm,99);
    printf("ret expect 1,actual %lu\n",ret);
}

void TestClear(){
    PRINT_HEAD;
    Bitmap bm;
    BitmapInit(&bm,100);
    BitmapFill(&bm);
    uint64_t  ret =  BitmapTest(&bm,50);
    printf("ret expect 1,actual %lu\n",ret);
    ret =  BitmapTest(&bm,0);
    printf("ret expect 1,actual %lu\n",ret);
    ret = BitmapTest(&bm,99);
    printf("ret expect 1,actual %lu\n",ret);
    BitmapClear(&bm);
    ret =  BitmapTest(&bm,50);
    printf("ret expect 0,actual %lu\n",ret);
    ret =  BitmapTest(&bm,0);
    printf("ret expect 0,actual %lu\n",ret);
    ret = BitmapTest(&bm,99);
    printf("ret expect 0,actual %lu\n",ret);
}

int main(){
    TestInit();
    TestDestroy();
    TestSet();
    TestUnset();
    TestFill();
    TestClear();
    return 0;
}

结果演示:

            


猜你喜欢

转载自blog.csdn.net/cecilia3333/article/details/80405217