[MIT6.006] 10. Open Addressing, Cryptographic Hashing 开放定址,加密哈希

前几节课讲散列表的时候,我们需要用Chaining,链接法需要用到指针pointer,但有一种方法可以不要Chaining和指针,还能在发生冲突时,为产生冲突的关键字寻找下一个“空”的Hash地址。这种方法叫:开放定址法(Open Addressing)如下图所示:

在开放定址法中,用到探测法(Probing),它是让Hash函数指定slot的顺序去进行关键字key的探索,从而进行插入/查找/删除操作。简单来说,上图的例子就能看懂probing的运作机制了。为了方便确认slot是否已有关键字占用,为每个slot定义个flag,如果无占用就是None。

下面我们看下在开放定址下,它是如何进行插入/查找/删除操作

对上图翻译如下:

  • 插入(k,v):一直探测,直到一个空的slot出现,然后插入进去。注:k为要插入的数,v为散列表尝试插入的次数。
  • 查找(k):只要slot上的关键字不等于k,则不断探测下去,直到遇到key=k的情况(返回:成功),或者遇到空slot(返回:失败)。
  • 删除:删除简单来说就先用上面查找方式找到待删除k的位置,然后删除即可。但是如果散列表第1个slot就是空slot,那么查找(k)会返回失败的结果,然后实际上并不一定是对的,上图列子可以说明这一点。比如我先删除了586,之后要删496,散列表第1个位置上slot为空,则返回失败,这是不对的,因为496在散列表第3个位置上。这个时候为了解决这个问题,就加入了DeleteMe flag,如果第一个位置上586被删除了,则设DeleteMe != None,当要删496时,碰到DeleteMe != None时,跳过该位置,继续向下探测。需要注意的是,对于插入来说 DeleteMe和None没什么区别,只要为空就可以插入。

探测方法有几种,本课就讲了两种:线性探测法(Linear Probing)再散列法(Double Hashing Probing)

首先,如下图,线性探测法的散列函数为:h(k, i) = (h'(k) + i) mod m   (其中h'(k)为正常的散列函数)。但这种方法有个弊端:线性探测法可能使第i个散列地址的同义词存入第i+1个散列地址,这样原本应存入第i+1个散列地址的元素就争夺第i+2个散列地址,从而造成大量元素在相邻的散列地址上“聚集”起来,减低了查找效率。

扫描二维码关注公众号,回复: 10660390 查看本文章

为了解决线性探测的聚集问题,可以使用再散列法,它的公式为:h(k, i) = (h1(k) + i * h2(k)) mod m(其中h1(k)和h2(k)两种不同的普通散列函数)。

课程的最后提到Uniform Hashing Assumption,如下图所示,具体的cost of operation instert作者没有讲的太细,所以我这边也没太看明白。而最后作者提到了密码加密的机制,简单来说就是一个密码x123456,然后你用hash(k=x123456)后保存在数据库中,因此想要猜到哈希加密后的密码是很难的。

猜你喜欢

转载自www.cnblogs.com/alvinai/p/12673770.html
今日推荐