位图的实现(BitSet||BitMap)

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为33,33/8=4,但是要5个字节才能存的下
	size_t size = n >> 3 + 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;
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值