位向量(bit vector)是一个仅包含0和1的数组。长度为m的位向量所占空间要比包含m个指针的数组少的多。用一个位向量来表示一个包含不同元素的动态集合。字典操作的运行时间为0(1)
代码:
#include <stdio.h>
#include <stdlib.h>
#define INT_BIT 32
typedef struct {
unsigned int *table;
int size;
} BitMap;
BitMap * bitmap_create(int max)
{
BitMap *bitmap = (BitMap *)malloc(sizeof(BitMap));
bitmap->size = max / INT_BIT + 1;
printf("bitmap->size=%d",bitmap->size);
bitmap->table =(unsigned int *) calloc(sizeof(int), bitmap->size);
return bitmap;
}
//void bitmap_insert(BitMap *bitmap, int key)
//{
// bitmap->table[key / INT_BIT] |= (1 << (key % INT_BIT));
//}
//
//void bitmap_delete(BitMap *bitmap, int key)
//{
// bitmap->table[key / INT_BIT] &= ~(1 << (key % INT_BIT));
//}
//
//int bitmap_search(BitMap *bitmap, int key)
//{
// return bitmap->table[key / INT_BIT] & (1 << (key % INT_BIT));
//}
void bitmap_insert(BitMap *bitmap,int key)
{
bitmap->table[key/INT_BIT]|=1<<(key%INT_BIT);
}
void bitmap_delete(BitMap *bitmap,int key)
{
bitmap->table[key/INT_BIT]&=~(1<<(key%INT_BIT));
}
int bitmap_search(BitMap *bitmap,int key)
{
int m=bitmap->table[key/INT_BIT]&(1<<(key%INT_BIT));
return m;
}
void bitmap_print(BitMap *bitmap)
{
printf("-----\n");
int i;
for (i = 0; i < bitmap->size; i++)
if (bitmap->table[i] != 0)
printf("%d: %d\n ", i, bitmap->table[i]);
printf("-----\n");
}
int main(void)
{
BitMap *bitmap = bitmap_create(1024);
bitmap_insert(bitmap, 15);
bitmap_delete(bitmap, 15);
bitmap_insert(bitmap, 520);
bitmap_insert(bitmap, 900);
bitmap_print(bitmap);
printf("%d\n", bitmap_search(bitmap, 68));
printf("%d\n", bitmap_search(bitmap, 15));
printf("%d\n", bitmap_search(bitmap, 520));
printf("%d\n", bitmap_search(bitmap, 900));
return 1;
}
结果:
结果当中0 0是表示没有这两个数字。256表示是第8位是1的这个特征存储了520这个数字。该算法不能正确表示出来这个数字。这个是缺点。
应用:
位向量可以利用少量的空间保存大量的数据。
假如1M的空间一共可以用32位寻址来表示。那可以利用这个性质转换到直接定址法中,一个不同的地址可以保存一个数,也就是通过01向量法来表示出这个数字来。一共可以表示2^32个数。所以腾讯有一道面试题目:给几十万个不同的数字,然后没有排序,给你一个数字M,怎样判断这几十万个数字里面是不是有这个M,就可以通过位向量方法来解决。