位图数据结构描述了一个有限定义域内的稠密集合,其中的每一个元素最多出现一次并且没有其他数据与该元素相关联。在内存空间有限的条件下,在相同的内存下,位图数据结构可以存储远远比用其他数据类型存储多得多的数据,同时在时间要也是一个不错的选择;
位图数据结构的通过用每一位保存一个数,多个位组成一个基本数据类型,多个同一数据类型形成一个数组,比如int有四个字节,32位,可以保存32个数分别是0~31,int[2]总共有64个位,可以保存0~63之间的数,依次类推,当然数据类型不局限与int,也可以是其他。可以看出位图数据结构有一个优点,那就是所需空间少,可以极大的利用空间。
以下是位图数据结构的具体实现步骤:
//位图数据结构
#include<stdio.h>
#include <stdlib.h>
#define SIZE 5 //数组的大小,主要是测试用,可以更大
void init(int *bm); //初始化
void Setbit(int *bm,int n); //设置第n位,即保存数n
void Clearbit(int *bm,int n);//对n位清零,即删除数n
int Testbit(const int *bm,int n); //判断n是否存在
//初始化
void init(int *bm)
{
int i;
for(i = 0;i < SIZE;i++)
bm[i] = 0;
}
//设置第n位
//n>>5相当于n/32;定位到n保存数组的第几个元素中
//n&0x1F相当于n%32,由于移位运算,当n
//比如35;35>>5 = 1,35&0x1F = 3即35保存的位置为第1个元素的第3位
void Setbit(int *bm,int n)
{
if(n <0 || n > SIZE*32)
printf("%d 不存在,小于0或者大于最大值!\n",n);
bm[n>>5] |= (1<<(n&0x1F));
}
//清楚第n位
void Clearbit(int *bm,int n)
{
if(n < 0 || n > SIZE*32)
printf("%d 不存在,小于0或者大于最大值!\n",n);
bm[n>>5] &= (~(1<<(n&0x1F)));
}
//测试第n位是否存在
int Testbit(const int *bm,int n)
{
if(n < 0 || n > SIZE*32)
printf("%d 不存在,小于0或者大于最大值!\n",n);
return bm[n>>5] & (1<<(n&0x1F)) ;
}
//测试
int main()
{
int a[SIZE];
int i = 0,n,temp;
init(a);
printf("请输入数量:");
scanf("%d",&n);
printf("请输入数据(%d个):",n);
for(i = 0;i < n;i++)
{
scanf("%d",&temp);
Setbit(a,temp);
}
for(i = 0;i < SIZE*32;i++)
{
if(Testbit(a,i))
printf("%5d",i);
}
printf("\n");
return 0;
}
其实,一路下来,位图的实现相对来说并不难,甚至相比其他数据结构来说比较简单,其中的位运算主要是加快运行速度,由于其实现简单,我们也可以通过宏进行实现。不过位图数据结构也有局限性,就如同前面所提到的,数据必须无重复,同时数据的大小必须小于你所使用的数组(或其他)的大小(位的个数)同时在读出排序后的元素时,由于需要扫描数组,而且是一个一个位进行扫面,在数据比较大,但个数少的时候,可能就有点得不偿失了;
——如有错误的地方,欢迎指正,如有问题,欢迎留言