zoukankan      html  css  js  c++  java
  • 哈希冲突详解、拉链法、开地址法

    哈希冲突详解

    什么是哈希冲突?

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

      同样的当数据插入到哈希表时,不同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接近的素数。

    二次探查法详解

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

    双散列法详解

      使用双散列方法可以避免二级聚集。双散列法使用两个散列函数,第一个散列函数计算探针序列的起始值,第二个散列函数计算下一个位置的探查步长。
     
  • 相关阅读:
    HDU1251统计难题map+输入
    HDU1863畅通工程
    POJ2253 Frogger
    HDU 4725 (The Shortest Path in Nya Graph)层次网络
    hdu5521(Meeting)spfa 层次网络最短路
    Fire Net ZOJ 1002
    POJ3259(Wormholes) 判断负环
    POJ3268(Silver Cow Party)
    棋盘问题 POJ 1321
    POJ 1661 (Help Jimmy )
  • 原文地址:https://www.cnblogs.com/bsjl/p/8628435.html
Copyright © 2011-2022 走看看