数据结构与算法学习03-Hash&BloomFilter

hash

hash的应用

  • word 判断某个单词是否拼写正确
  • 网络爬虫防止爬相同url
  • 垃圾邮件过滤算法
  • 缓存穿透问题

不难看出,这些问题都可以看做是基于一个字符串,查找它在大的字符串集中是否存在。

hash的实现

和平衡多路搜索树比较,hash是通过一个映射函数,通过key获得key的地址。可以表示为 hash(key) = addr。

选择一个hash函数要满足以下性质:

  • 计算速度快
  • 随机分布性强(等概率,均匀分布)
  • murmurhash1, murmurhash2, murmurhash3 速度 2 > 3 > 1 质量 3>2>1,一般使用2; siphash(redis6), 主要解决字符串接近的强随机分布性;cityhash。
  • 操作流程
struct node{
	void* key;
	void* val;
	struct node* next;
};

插入: h(key)%size 获得 pos
hash冲突 :多个 key 计算的 pos 是同一个,描述冲突的激烈程度(负载因子),数组存储的元素个数/数组长度,解决冲突(链表法,把冲突用链表存放,合理范围 used < size,这里存放同一个key的value的单链表,在超过256的时候可以换成红黑树或者堆,开放寻址法,位置被使用就双重哈希解决hash聚集现象。),如果负载因子不在合理范围内,就要使用扩容(解决冲突)和缩容(节约空间),再 rehash 。

STL中 unordered_* 的实现(散列表实现)

map set multimap multiset 是用红黑树实现的,unordered_map unordered_set unordered_multimap unordered_multiset 是用散列表实现的
散列表 Hashtable
hash
本质上,插入使用的是头插法,整个表是一个单链表方便实现迭代器。

BloomFilter

使用场景

内存有限,只想确定某个key存不存在,不需要value的值。

构成

位图(bit数组) + n 个hash函数
m%2n = m &(2n -1)
bloomfilter
插入:在位图相应位置赋值 1
查找不存在: 有一个hash位置为0就不存在
布隆过滤器不支持删除操作,因为他不清楚这个1是被那个hash映射的,被多少hash映射的
所以,布隆过滤器 应用在 不用删除的,判断一个key是不是不存在的场景。判断一个key是不是存在也可以,但是要假阳率可控的条件下。

使用

四个参数
n p m k
N 预期存多少个元素
P 允许的假阳率 10e-7就是一千万里面允许错一次
M 位图空间的大小
K hash函数的数量

问题:用2G内存在2e14个数中找到出现次数最多的数
存储 散列表 k 整数(四字节 -2147483648到2147483647) v 出现次数(uint32 -2147483648 到 2147483647)
一个 kv 8字节 2亿 个 8字节 就是 1.6G内存,20亿个数就是 16G内存
所以把 20 亿个数拆成 多 份,每份 < 2G,把相同的整数放到同一个文件中,可以用hash的强随机分布性来做这件事,使得每个文件中分布数量均匀。求每份中出现数最多的数,再将多个文件的最大次数做比较。
总结:大文件 hash 拆成小文件,单台机器 hash 分流到多台机器(强随机分布性和hash函数选择数据)
hash一致性(解决扩容后 映射变化)
因为扩容时,算法发生改变,缓存失效
解决方法:固定算法(还是有局部失效),再做hash数据迁移。样本数越大越稳定,样本数少不稳定,可以增加虚拟结点(来保证数据均衡),增加样本数,使得迁移数据量变少。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值