位图的实现(BitSet||BitMap)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hansionz/article/details/82585228
0.位图的概念

在哈希表中,如果要在表中存放一个整数,此时就要申请一个整型的空间来存放它,一个整型数据在32位或64位平台下都占4个字节。但是如果现在需要存储的数据是40亿个不重复的无符号整型,就需要160亿个字节来存储,1GB的内存是10亿个字节,那么160亿个字节需要16GB的内存来存放这些数据,而我们普通的电脑内存一般都是4G的内存,这显然是存放不下的。

这就引入了位图的概念:内存中的最小单位是比特。如果能用一个比特位来存放一个整型,只需要0.5GB(一个比特位可以表示一个整型,也就是4个字节,一个字节8个比特位那么总共需要5亿个字节的空间,既0.5G)的内存。但是一个比特位只可以表示0或1两种状态。如果要表示40亿个数据,可以申请0.5GB的内存。如果要存放的数据为10,映射到第10个比特位设置为1。如果要查找的数据为100,就查看第100个比特位处的状态,如果为1说明100存在于这堆数据中,如果是0说明不存在。这样用一个位来标识一个数据在或者不在的结构就是位图,实际上是哈希表的一种变形。

0.定义结构
//位图结构
typedef struct BitSet
{
    char* _a;//也可以用其他的类型开辟数据
    size_t _N;//位个数
}BitSet;
3.函数实现
#include "BitSet.h"
//初始化位图
void BitSetInit(BitSet* pbs, size_t n)
{
    assert(pbs);

    pbs->_N = n;
    //这里一定要加1,假如n为25,25/8=4,但是要5个字节才能存的下
    size_t size = n / 8 + 1;
    //开辟空间
    pbs->_a = (char*)malloc(size);
    //初始化为0
    memset(pbs->_a, 0, size);
}
//销毁位图(释放malloc出来的空间)
void BitSetDestory(BitSet* pbs)
{
    assert(pbs);

    free(pbs->_a);
    pbs->_a = NULL;

    pbs->_N = 0;
}
//设置要存的值位置为1
void BitSetSet(BitSet* pbs, size_t x)
{
    assert(pbs);

    int index = x >> 3;//计算在第几个char里,相当于/8
    int num = x % 8;//计算在第几位

    pbs->_a[index] |= (1 << num);   
}
//把已经设置为1的位置重新设置为0
void BitSetReSet(BitSet* pbs, size_t x)
{
    assert(pbs);

    int index = x >> 3;//相当于/8
    int num = x % 8;

    pbs->_a[index] &= ~(1 << num);
}
//判断所给数字是否存在(存在返回1,不存在返回0)
int BitSetTest(BitSet* pbs, size_t x)
{
    assert(pbs);

    int index = x >> 3;//相当于/8
    int num = x % 8;

    int ret = pbs->_a[index] & (1 << num);

    if (0 == ret)
    {
        return 0;
    }
    else
        return 1;
}

下边是测试代码:

#include"BitSet.h"
void TestBitSet()
{
    BitSet bs;
    BitSetInit(&bs, 20);

    BitSetSet(&bs, 14);
    BitSetSet(&bs, 2);
    BitSetSet(&bs, 9);
    BitSetSet(&bs, 19);
    BitSetReSet(&bs, 19);
    printf("%d\n", BitSetTest(&bs, 19));
    printf("%d\n", BitSetTest(&bs, 3));
    printf("%d\n", BitSetTest(&bs, 9));
    printf("%d\n", BitSetTest(&bs, 4));

    BitSetDestory(&bs);
}
int main()
{
    TestBitSet();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/hansionz/article/details/82585228