位图(Bitmap)详解

📌 温馨提示:
本文内容可能随时间变动而失效,请以页面显示的更新时间为准。
若内容已不准确或资源失效,欢迎留言或联系站长反馈修正。
⚠️ 免责声明:
本文仅供学习与参考,观点仅代表作者个人意见,与本站无关。
如有侵权问题,请立即联系我们处理,谢谢理解与支持。

位图(Bitmap)是一种使用二进制位(bit)来存储数据状态的结构,常用于大规模数据去重、状态标记、高效存储等场景。


🧠 1. 什么是位图?

位图是一种紧凑的数组结构,用 0/1 表示某个状态是否存在,占用空间非常小,适合存储布尔状态或整数集合。

比如要表示 0 ~ 15 的数字是否存在:

原始数组:[0, 1, 3, 7]
位图表示:10001001 00000001 (高位在左)
           ↑   ↑     ↑    ↑
           0   1     3    7

🧮 2. 基本原理

2.1 结构定义

位图是一种 bit 数组,通常使用整数类型来表示一组 bit:
- 1 个字节(Byte) = 8 个 bit
- 1 个 int(32 位系统) = 32 个 bit

2.2 空间计算

要表示 N 个非负整数,需要的内存大小为:

内存大小 = N / 8 字节(byte)

举例:如果要表示 1 亿个数字(最多 1e8 个),需要约:

1e8 / 8 = 12.5 MB

⚙️ 3. 位图的操作

3.1 设置某位为 1(标记存在)

bitmap[index / 8] |= (1 << (index % 8));

3.2 清除某位为 0(标记不存在)

bitmap[index / 8] &= ~(1 << (index % 8));

3.3 判断某位是否为 1(是否存在)

if (bitmap[index / 8] & (1 << (index % 8))) {
    // 存在
}

🛠️ 4. 示例代码(C语言)

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

#define MAX_NUM 100000000

unsigned char *bitmap;

void setBit(int num) {
    bitmap[num / 8] |= (1 << (num % 8));
}

void clearBit(int num) {
    bitmap[num / 8] &= ~(1 << (num % 8));
}

int testBit(int num) {
    return bitmap[num / 8] & (1 << (num % 8));
}

int main() {
    bitmap = (unsigned char *)calloc(MAX_NUM / 8 + 1, sizeof(unsigned char));

    setBit(123);
    setBit(99999);

    if (testBit(123)) {
        printf("123 exists\n");
    }

    if (!testBit(88888)) {
        printf("88888 does not exist\n");
    }

    free(bitmap);
    return 0;
}

📦 5. 位图的应用场景

- 去重(大数据判重)
- 排序(外排序的替代方案)
- Bloom Filter 的底层实现
- 状态标记(如是否已访问)
- 离线数据标记、日志处理
- 网络流量记录

⚖️ 6. 优点与缺点

✅ 优点

- 空间效率高:bit 级别控制
- 时间复杂度 O(1):插入、查询、删除都很快

❌ 缺点

- 只能用于非负整数
- 无法存储复杂结构
- 存在稀疏浪费问题(若数据集中但范围大)

📚 7. 相关拓展

  • 布隆过滤器(Bloom Filter)
  • 通过多个位图和多个哈希函数实现更高效的去重
  • 压缩位图(Roaring Bitmap)
  • 用于优化稀疏位图的存储问题
  • Java BitSet
  • Java 中的位图实现类

🧪 8. 位图 vs 哈希表

特性位图(Bitmap)哈希表(HashSet)
空间占用极小较大
时间复杂度O(1)O(1)
是否支持负数否(需偏移)
是否支持泛型
最大支持数量高(10 亿级)中等(百万级)

✅ 总结

位图是一种非常高效的空间压缩数据结构,适用于大规模数据的快速去重与存在性判断。但在存在负数或非整数、数据稀疏等场景下,需结合其他结构(如哈希表、布隆过滤器)使用。

THE END
喜欢就支持一下吧
点赞14
相关推荐
评论 抢沙发

请登录后发表评论

    暂无评论内容