哈希

哈希概念

在顺序结构或者平衡树中,找到一个元素要经过多次比较,在顺序结构中可能要经历O(N)次,在平衡树中也要经过 O(log2N)。而哈希则建立了一种映射关系,比如说在ASCII码中,小写字母’a’对应的ASCII码是97,'a’和97便是一种映射关系,通过这种映射关系,就能更快的找到一个元素。

哈希冲突

哈希中找到映射关系所使用的转换函数称为哈希函数,构造出来的结构称为哈希表。
例如如下的哈希函数:hash(key) = key % capacity。
在这里插入图片描述
不同的关键字通过相同的哈希函数计算出了相同的哈希地址,这种现象就称为哈希碰撞或者哈希冲突。

哈希冲突的解决

闭散列

闭散列:也叫开放定址法,当发生哈希冲突时,如果哈希表未被装满,说明在哈希表中必然还有空位置,那么可以把key存放到冲突位置中的“下一个” 空位置中去。
在这里插入图片描述
查找: 先找到要查找的元素经过哈希函数之后映射的位置,如果有元素存在不是要查找的,则依次往后查找,如果映射的位置没有元素存在,则要查找的元素也不存在。

但是这样又出现了一个问题。当删除4时,44的位置不就出问题了?当表中仅有44时,对应的哈希地址应该是4,现在却对应了5,查找44的时候,就会出问题。

删除: 所以要在每个位置做相应的标记,如果要删除一个元素,则删除之后,把相应的位置标记为删除,而不是不存在。如果一个位置不存在,那就标记为不存在。现在如果删除4这个元素,那就要在这个位置标记为删除,当查找44的时候,首先查找到4这个位置,这个位置如果标记为不存在,则直接返回无44,如果标记为删除,则依次往后查找。

增容
闭散列中,如果产生哈希冲突,就会插入到下一个空的位置,那迟早哈希表会满的,为了减少哈希冲突和解决哈希表满的情况,当负载因子(哈希表中元素个数 / 哈希表容量)(假如元素个数为7,容量为10,负载因子就是0.7)达到一定程度,就进行增容,并且对哈希表中的元素重新分配位置。
在这里插入图片描述

开散列

开散列法又叫链地址法(开链法),首先对关键码集合用散列函数计算散列地址,具有相同地址的关键码归于同一子集合,每一个子集合称为一个桶,各个桶中的元素通过一个单链表链接起来,各链表的头结点存储在哈希表中
在这里插入图片描述
增容: 开散列最好的情况是:每个哈希桶中刚好挂一个节点,再继续插入元素时,每一次都会发生哈希冲突,因此,在元素个数刚好等于桶的个数时,可以给哈希表增容

哈希的应用

unordered_map 和 unordered_set

unordered_map在线文档
unordered_set在线文档

位图

位图,就是用每一位来存放某种状态,适用于海量数据,数据无重复的场景。通常是用来判断某个数据存不存在的。数据是否在给定的整形数据中,结果是在或者不在,刚好是两种状态,那么可以使用一个二进制比特位来代表数据是否存在的信息,如果二进制比特位为1,代表存在,为0代表不存在

例如:给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。
如果用int型的数组来存,那40亿个数,数组会耗费很大的空间,如果用位图来存,可以减少32倍!

布隆过滤器

如果想表示某个元素存不存在,如果单独用哈希,则浪费空间,单独用位图则不能处理哈希冲突,所以将哈希和位图结合起来,便有了布隆过滤器。
如果要表示一个元素存在,则用多个哈希函数,将一个数据映射到位图上即可。
在这里插入图片描述
查找:
用多个哈希函数,找到映射的多个位置,如果都为1,则可能存在,如果有一处为0,则肯定不存在。因为有可能不同的元素映射到相同的位置上,所以只能判断一个元素不存在或者可能存在

删除: 不能单独去将某个元素用多个哈希映射的位置的删除,因为可能别的元素也对应在这个位置,可以将每一个比特位扩展成计数器,删除的时候,计数减一即可。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值