高级数据结构 布隆过滤器

赶工ing

引言

思考:要经常判断1个元素是否存在,需要怎么做?

Answer:很容易想到哈希表(HashSet、HashMap),元素作为 key 去查找。查找元素过程,使用O(1)时间计算出数组索引(哈希值即为 数组下标),接着每个数组下标指向一颗红黑树(链地址法处理哈希冲突),使用常数级别的时间复杂度去查找对应的value是否存在即可

  • 理由:时间复杂度仅为O(1)
  • 缺点:空间利用率不高,需要占用比较多的内存资源

需求:如果需要编写一个网络爬虫去爬10亿个网站数据,为了避免爬到重复的网站,如何判断某个网站是否爬过?

  • 很显然,HashSet、HashMap 并不是非常好的选择,需要占用大量空间
  • 是否存在时间复杂度低、占用内存较少的方案?
    • 布隆过滤器(Bloom Filter)

布隆过滤器简介

1970年由布隆提出的一种数据结构。它是一个 空间效率高的概率型数据结构。

作用:判断一个元素 一定不存在 或者 可能存在

优缺点:

  • 优点:空间效率 和 查询时间都远远超过 一般算法
  • 缺点:有一定的误判率、删除困难

布隆过滤器的本质:实际上是一个很长的二进制向量一系列随机映射函数(Hash函数)

常见应用:网页黑名单系统、垃圾邮件过滤系统、爬虫的网址判重系统、解决缓存穿透问题

应用布隆过滤器的需求场景

  1. 需要判断某个元素是否存在
  2. 元素数量巨大,希望用比较少的内存空间
  3. 允许有一定的误判率

布隆过滤器原理

假设: 布隆过滤器由 20位二进制、 3 个哈希函数组成,每个元素经过哈希函数处理都能生成一个索引位置

  • 添加元素:将每一个哈希函数生成的索引位置都设为 1
  • 查询元素是否存在
    • 如果有一个哈希函数生成的索引位置不为 1,就代表不存在(100%准确)
    • 如果每一个哈希函数生成的索引位置都为 1,就代表可能存在(存在一定的误判率)

image.png

复杂度分析

  • 添加、查询时间复杂度:O(k),k为 哈希函数个数

  • 空间复杂度:O(m),m是二进制位的个数

布隆过滤器误判率

布隆过滤器实现

附录

参考文献

版权信息

本文原载于kitebin.top,遵循CC BY-NC-SA 4.0协议,复制请保留原文出处。

CC BY-NC-ND
最后更新于 Jun 10, 2024 09:42 UTC
Built with Hugo
主题 StackJimmy 设计