哈希冲突详解(拉链法,开放地址法)

哈希冲突详解


我喜欢用问答的形式来学习,这样可以明确许多不明朗的问题。

  1. 什么是哈希冲突?

比如我们要去买房子,本来已经看好的房子却被商家告知那间房子已经被其他客户买走了。这就是生活中实实在在的冲突问题。

同样的当数据插入到哈希表时,不同key值产生的h(key)却是相等的,这个时候就产生了冲突。这个时候就要解决这个问题。

  • 怎么解决哈希冲突?

    方法1:拉链法 
    方法2:开地址法

  • 何为拉链法?

    拉链法是解决哈希冲突的一种行之有效的方法,某些哈希地址可以被多个关键字值共享,这样可以针对每个哈希地址建立一个单链表。

    在拉链(单链表)的哈希表中搜索一个记录是容易的,首先计算哈希地址,然后搜索该地址的单链表。

    在插入时应保证表中不含有与该关键字值相同的记录,然后按在有序表中插入一个记录的方法进行。针对关键字值相同的情况,现行的处理方法是更新该关键字值中的内容。

    删除关键字值为k的记录,应先在该关键字值的哈希地址处的单链表中找到该记录,然后删除之。

  • 什么是开地址法?

    首先该方法并不建立链表。哈希表由M个元素组成,其地址从0到M-1。我们通过从空表开始,逐个向表中插入新记录的方式建立散列表。 
    插入关键字值为key的新纪录的方法是: 
    从h(key)开始,按照某种规定的次序探查插入新记录的空位置。h(key)被称为基位置。如果h(key)已经被占用,那么需要用一种解决冲突的策略来确定如何探查下一个空位置,所以这种方法又称为空缺编址法。 
    根据不同的解决冲突的策略,可以产生不同的需要被检查的位置序列,称为 探查序列。 
    根据生成的探查序列的不同规则,可以有 线性探查法伪随机探查法二次探查法 和 双散列法等开址方法。

  • 线性探查法详解

    缺点:线性探查法在情况不好的时候导致许多记录在散列表中连成一片,从而使探查次数增加,影响搜索效率。这种现象称为基本聚集

    线性探查法是一种简单的开地址方法,它使用下列循环探查序列:

    h(key),h(key)+1,...,M-1,0,...,h(key)-1

    从基位h(key)开始探查该位置是否被占用,即是否为空位置。 
    如果被占用,则继续探查位置h(key)+1,若该位置也已占用,再根据探查序列中的规定继续检查下一个位置。 
    因此,探查序列为:

    h(i) = (h(x)+i) % M (i=0,1,2,...,M-1)
  • 伪随机法详解

    伪随机法是为了消除线性探查的基本聚集而提出来的方法。其基本思想是建立一个伪随机数发生器。当发生冲突时,就利用伪随机数发生器计算下一个探查位置。伪随机数发生器有不同的构造。

    一个比较简单的伪随机数产生方法:

       
       y(0) = h(key)
       y(i+1) = (y(i)+p) % M  (i=0,1,2,...)
    式中,y(0)为伪随机数发生器的初值,M为哈希表的长度,
    P为与M接近的素数。
    
  • 二次探查法详解

    二次探查法也能够消除基本聚集,虽然伪随机数法和二次探查法都能够消除基本聚集。但是如果两个关键字值有相同的基本位置,那么它们就会有相同的探查序列。这是因为伪随机数法和二次探查产生的探查序列是基位置的函数,而不是原来关键字的函数,因此由产生了二次聚集的问题。

  • 双散列法详解 

    使用双散列方法可以避免二级聚集。双散列法使用两个散列函数,第一个散列函数计算探针序列的起始值,第二个散列函数计算下一个位置的探查步长。

posted @ 2018-08-18 00:11  strawqqhat  阅读(2017)  评论(0编辑  收藏  举报
#home h1{ font-size:45px; } body{ background-image: url("放你的背景图链接"); background-position: initial; background-size: cover; background-repeat: no-repeat; background-attachment: fixed; background-origin: initial; background-clip: initial; height:100%; width:100%; } #home{ opacity:0.7; } .wall{ position: fixed; top: 0; left: 0; bottom: 0; right: 0; } div#midground{ background: url("https://i.postimg.cc/PP5GtGtM/midground.png"); z-index: -1; -webkit-animation: cc 200s linear infinite; -moz-animation: cc 200s linear infinite; -o-animation: cc 200s linear infinite; animation: cc 200s linear infinite; } div#foreground{ background: url("https://i.postimg.cc/z3jZZD1B/foreground.png"); z-index: -2; -webkit-animation: cc 253s linear infinite; -o-animation: cc 253s linear infinite; -moz-animation: cc 253s linear infinite; animation: cc 253s linear infinite; } div#top{ background: url("https://i.postimg.cc/PP5GtGtM/midground.png"); z-index: -4; -webkit-animation: da 200s linear infinite; -o-animation: da 200s linear infinite; animation: da 200s linear infinite; } @-webkit-keyframes cc { from{ background-position: 0 0; transform: translateY(10px); } to{ background-position: 600% 0; } } @-o-keyframes cc { from{ background-position: 0 0; transform: translateY(10px); } to{ background-position: 600% 0; } } @-moz-keyframes cc { from{ background-position: 0 0; transform: translateY(10px); } to{ background-position: 600% 0; } } @keyframes cc { 0%{ background-position: 0 0; } 100%{ background-position: 600% 0; } } @keyframes da { 0%{ background-position: 0 0; } 100%{ background-position: 0 600%; } } @-webkit-keyframes da { 0%{ background-position: 0 0; } 100%{ background-position: 0 600%; } } @-moz-keyframes da { 0%{ background-position: 0 0; } 100%{ background-position: 0 600%; } } @-ms-keyframes da { 0%{ background-position: 0 0; } 100%{ background-position: 0 600%; } }