数据结构_位图

位图概念

基于哈希结构,在海量整型数据处理时,内存往往不够用,所以当只需要判断是否存在时,可以使用比特位来标记,一个整型数32个比特位,就可以标记32个数,如果有100亿个整数,就只需大约半个G的空间就可以处理,需要的空间大小和数据数量无关,和范围有关。
缺点:只能处理整型数

位图的建立

#pragma once

#include <stdlib.h>
#include <assert.h>
#include <string.h>

typedef struct BitMap
{
    size_t* _bits;
    size_t _range;
}BitMap;


//1bit
void BitMapInit(BitMap* bm, size_t range)  
{
    assert(bm);

    bm->_bits = (size_t*)malloc((sizeof(size_t)*range >> 5) + 1);
    assert(bm);
    memset(bm->_bits, 0, (sizeof(size_t)*range >> 5) + 1);
    bm->_range = (sizeof(size_t)*range >> 5) + 1;

}


void BitMapSet(BitMap* bm, size_t x)     //插入
{
    assert(bm);

    size_t frontin = x >> 5;
    size_t secondin = x % 32;

    bm->_bits[frontin] |= (1 << secondin);
}

void BitMapReset(BitMap* bm, size_t x)
{
    assert(bm);

    size_t frontin = x >> 5;
    size_t secondin = x % 32;

    bm->_bits[frontin] &= ~(1 << secondin);

}

// x存在返回0,不存在返回-1 
int BitMapTest(BitMap* bm, size_t x)
{
    assert(bm);

    size_t frontin = x >> 5;
    size_t secondin = x % 32;

    if ((bm->_bits[frontin] & (1 << secondin)) == 0)
    {
        return -1;
    }
    else return 0;
}

void BitMapDestory(BitMap* bm)
{
    assert(bm);

    free(bm->_bits);
    bm->_bits = NULL;
    bm->_range = 0;
}




void BitMapHave(BitMap* bm1, BitMap* bm2)
{
    assert(bm1);
    assert(bm2);

    size_t i = 0;
    for (i = 0; i < bm1->_range; i++)
    {
        size_t tmp = bm1->_bits[i] & bm1->_bits[i];
        if ( tmp != 0)
        {
            for (size_t j = 0; j < 36; j++)
            {
                if ((tmp&(1 << j)) != 0)
                {
                    printf("%d ", i * 32 + j);
                }
            }
            printf("\n");
        }
    }
}

//2bit
void BitMapInitTwo(BitMap* bm, size_t range)
{
    assert(bm);

    bm->_bits = (size_t*)malloc((sizeof(size_t)*range >> 4) + 1);
    assert(bm);
    memset(bm->_bits, 0, (sizeof(size_t)*range >> 4) + 1);
    bm->_range = (sizeof(size_t)*range >> 4) + 1;
}

void BitMapSetTwo(BitMap* bm, size_t x)     //插入
{
    assert(bm);

    size_t index = x >> 4;
    size_t left = x % 16 * 2;
    size_t right = x % 16 * 2+1;

    if ((bm->_bits[index] & (1 << left))== 0 
        && (bm->_bits[index] & (1 << right)) == 0)    //00不存在
    {
        bm->_bits[index] |= (1 << right);
    }
    else if ((bm->_bits[index] & (1 << left)) == 0
        && (bm->_bits[index] & (1 << right)) != 0)    //01存在一个
    {
        bm->_bits[index] |= (1 << left);
        bm->_bits[index] &= ~(1 << right);
    }
    else if ((bm->_bits[index] & (1 << left)) != 0
        && (bm->_bits[index] & (1 << right)) == 0)   //10存在两个
    {
        bm->_bits[index] |= (1 << right);
    }

}

//不存在返回-1  一个返回1  两个返回 2 两个以上返回3
int BitMapTestTwo(BitMap* bm, size_t x)
{
    assert(bm);

    size_t index = x >> 4;
    size_t left = x % 16 * 2;
    size_t right = x % 16 * 2 + 1;


    if ((bm->_bits[index] & (1 << left)) == 0
        && (bm->_bits[index] & (1 << right)) == 0)    //00
    {
        return -1;
    }
    else if ((bm->_bits[index] & (1 << left)) == 0
        && (bm->_bits[index] & (1 << right)) != 0)     //01
    {
        return 1;
    }
    else if ((bm->_bits[index] & (1 << left)) != 0
        && (bm->_bits[index] & (1 << right)) == 0)    //10
    {
        return 2;
    }
    else if ((bm->_bits[index] & (1 << left)) != 0
        && (bm->_bits[index] & (1 << right)) != 0)      //11
    {
        return 3;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值