bitmap.h
#pragma once
#include<stdbool.h>
#include<stdint.h>
#include<stdlib.h>
typedef uint32_t Word;
typedef struct {
Word* array;
size_t bits;
}BitMap;
BitMap* bitmap_create(size_t bits);
void bitmap_destory(BitMap* bm);
void bitmap_set(BitMap* bm, size_t n);
void bitmap_unset(BitMap* bm, size_t n);
bool bitmap_isset(BitMap* bm, size_t n);
void bitmap_clear(BitMap* bm);
bitmap.c
#include"bitmap.h"
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#define BITS_PER_WORD 32
#define BITMAP_SHIFT 5
#define BITMAP_MASK 0x1F
//存储bits位,需要多少个word
#define BITMAP_SIZE(bits) ((bits+ BITS_PER_WORD -1) >> BITMAP_SHIFT)
BitMap* bitmap_create(size_t bits) {
BitMap* bm = malloc(sizeof(BitMap));
bm->array = calloc(BITMAP_SIZE(bits), sizeof(Word));
bm->bits = bits;
return bm;
}
void grow_capacity(BitMap* bm, size_t bits) {
Word* new_array = realloc(bm->array, BITMAP_SIZE(bits) * sizeof(Word));
if (new_array == NULL) {
printf("ERROR:relloc failed in grow_capacity\n");
exit(1);
}
bm->array = new_array;
int bytes = (BITMAP_SIZE(bits) - BITMAP_SIZE(bm->bits)) * sizeof(Word);
memset(bm->array + BITMAP_SIZE(bm->bits), 0, bytes);
}
void bitmap_set(BitMap* bm, size_t n) {
if (n >= bm->bits) {
if (BITMAP_SIZE(n + 1) > BITMAP_SIZE(bm->bits)) {
grow_capacity(bm, n + 1);
}
bm->bits = n + 1;
}
size_t word = n >> BITMAP_SHIFT;
size_t offset = n & BITMAP_MASK;
bm->array[word] |= (0x1 << offset);
}
void bitmap_unset(BitMap* bm, size_t n) {
size_t word = n >> BITMAP_SHIFT;
size_t offset = n & BITMAP_MASK;
bm->array[word] &= ~(0x1 << offset);
}
bool bitmap_isset(BitMap* bm, size_t n ) {
size_t word = n >> BITMAP_SHIFT;
size_t offset = n & BITMAP_MASK;
return bm->array[word] & (0x1 << offset);
}
void bitmap_clear(BitMap* bm) {
size_t bytes = BITMAP_SIZE(bm->bits) * sizeof(Word);
memset(bm->array, 0, bytes);
}
void bitmap_destory(BitMap* bm) {
free(bm->array);
free(bm);
}
应用场景,排序,去重,面试:用一个数据结构存储qq在线人数-》bitmap。
特点:内存紧凑。