数据结构| |位图

位图:也就是哈希表的变形,只是用一个bit位来存放一个数据。(准确来说是表示一个数据在该位置上存在不存在)

对于一个bit位,只可以存放0和1两种状态,所以位图只能解决的问题就是判断一个数据存在或者不存在。

代码实现:

//数据结构
typedef struct bitset
{
    char* _bits;
    int _size;
}bitset;

//各种函数的实现
//n代表的位的个数
void BitSetInit(bitset* phs, size_t n)
{
    assert(phs && n >= 0);

    //求出需要多少字节
    int bit = (n >> 3) + 1;

    phs->_bits = (char*)malloc(bit);
    if (phs->_bits == NULL)
    {
        perror("use malloc!\n");
    }

    memset(phs->_bits, 0, bit);
    phs->_size = n;
}

void BitSetDestory(bitset* phs)
{
    assert(phs);

    free(phs->_bits);
    phs->_bits = NULL;
    phs->_size = 0;
}

void BitSetSet(bitset* phs, size_t n)
{
    assert(phs && n >= 0);

    //先找到在那一个字节的位置
    int bit = n >> 3;
    int index = n % 8;

    phs->_bits[bit] |= (1 << index);
}

void BitSetReSet(bitset* phs, size_t n)
{
    assert(phs && n >= 0);

    int bit = n >> 3;
    int index = n % 8;

    phs->_bits[bit] ^= ~(1 << index);
}

//存在 1
//不存在 0
int BitSetCheck(bitset* phs, size_t n)
{
    assert(phs && n >= 0);

    int bit = n >> 3;
    int index = n % 8;

    return (phs->_bits[bit] & (1 << index)) == 0 ? 0 : 1;
}

可以采用位图做的题:
1.给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何判断一个数是否在40个亿个数中。
解:对于一般的算法的话,对于一堆数要判断一个数是否在这一堆数里面,一般都是先将这一堆数存放到内存中去,然后再去遍历对比看是否存在。(对于较少的数可以使用,即占用内存较小)

但是对于这个这个题,40亿个数,若是整数的话,即有160亿个字节,也就是16G,如果要放到内存中去查找的话,这明显优点效率太慢,不显示。所以就可以采用位图来解决这个问题。使用位图的话,就可以大幅度的节省空间,只是用2G的内存,这和16G进行对比,节省了许多的内存空间。

因为要判断一个数在不在话,那就是只有两种状态,存在或者不存在。刚好就相当于一个bit位可以用1或者0,来分别表示存在或者不存在。

所以就可以采用位图来解决这个问题。

采用位图的话也就是相当于哈希表一样。可以使用这个数来作为多少位。从而可以对该位进行设定。
2.给定100亿个整数,设计算法找到只出现一次的数
3.给定两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集
4.1个文件有100亿个int,1G内存,设计算法直到出现次数不超过两次的所有整数。

猜你喜欢

转载自blog.csdn.net/qq_40399012/article/details/82598205