双重散列探查法的计算公式

合集下载

双重散列探查法的计算公式

双重散列探查法的计算公式

双重散列探查法的计算公式双重散列是线性开型寻址散列(开放寻址法)中的冲突解决技术。

双重散列使用在发生冲突时将第二个散列函数应用于键的想法。

此算法使用:(hash1(key) + i * hash2(key)) % TABLE_SIZE来进行双哈希处理。

hash1()和hash2()是哈希函数,而TABLE_SIZE是哈希表的大小。

当发生碰撞时,我们通过重复增加步长i来寻找键。

第一个Hash函数:hash1(key) = key %TABLE_SIZE。

散列(Hashing)是计算机科学中一种对资料的处理方法,通过某种特定的函数/算法(称为散列函数/算法)将要检索的项与用来检索的索引(称为散列,或者散列值)关联起来,生成一种便于搜索的数据结构(称为散列表)。

二次再散列法是指第一次散列产生哈希地址冲突,为了解决冲突,采用另外的散列函数或者对冲突结果进行处理的方法。

设所有可能出现的关键字集合记为U(简称全集)。

实际发生(即实际存储)的关键字集合记为K(|K|比|U|小得多)。

散列方法是使用函数h将U映射到表T[0..m-1]的下标上(m=O(|U|))。

这样以U中关键字为自变量,以h为函数的运算结果就是相应结点的存储地址。

从而达到在O(1)时间内就可完成查找。

其中:①h:U→{0,1,2,…,m-1} ,通常称h为散列函数(Hash Function)。

散列函数h的作用是压缩待处理的下标范围,使待处理的|U|个值减少到m个值,从而降低空间开销。

②T为散列表(Hash Table)。

③h(Ki)(Ki∈U)是关键字为Ki结点存储地址(亦称散列值或散列地址)。

④将结点按其关键字的散列地址存储到散列表中的过程称为散列(Hashing)。

线性探测再散列查找成功和不成功的相关问题

线性探测再散列查找成功和不成功的相关问题

线性探测再散列法查找成功和查找不成功的平均查找长度Question1:将关键字序列(7、8、30、11、18、9、14)散列存储到散列表中。

散列表的存储空间是一个下标从0开始的一维数组,散列函数为:H(key) = (keyx3) MOD 7,处理冲突采用线性探测再散列法,要求装填(载)因子为0.7。

(1) 请画出所构造的散列表。

(2) 分别计算等概率情况下查找成功和查找不成功的平均查找长度。

Ans:(1).首先明确一个概念装载因子,装载因子是指所有关键子填充哈希表后饱和的程度,它等于关键字总数/哈希表的长度。

根据题意,我们可以确定哈希表的长度为L = 7/0.7 = 10;因此此题需要构建的哈希表是下标为0~9的一维数组。

根据散列函数可以得到如下散列函数值表。

H(Key) = (keyx3) MOD 7, 例如key=7时,H(7) = (7x3)%7 = 21%7=0,其他关键字同理。

Key 7 8 30 11 18 9 14H(Key) 0 3 6 5 5 6 0(表1)采用线性探测再散列法处理冲突,所构造的散列表为:地址0 1 2 3 4 5 6 7 8 9关键字7 14 8 11 30 18 9(表2)下面对散列表的构造方式加以说明,注意表1中的关键字7和14,30和9,11和18,这三组关键子的H(Key)值相同,这在构建散列表时就会产生冲突,因为他们的地址相同,所以要通过一定的冲突处理方法来解决这个问题。

依题,采用线性探测再散列法处理冲突。

下面详细介绍如何构建散列表:第一个key 7,它的地址是0,因此放到散列表的数组下表为0的位置,这个位置上没有关键字,因此没有冲突可以直接填入;第二个key 8,它的地址是3,因此放到散列表的数组下表为3的位置,这个位置上没有关键字,因此没有冲突可以直接填入;第三个key 30,它的地址是6,因此放到散列表的数组下表为6的位置,这个位置上没有关键字,因此没有冲突可以直接填入;第四个key 11,它的地址是5,因此放到散列表的数组下表为5的位置,这个位置上没有关键字,因此没有冲突可以直接填入;第五个key 18,它的地址是5,因此放到散列表的数组下表为5的位置,但这个位置上已经有关键字11,遇到了冲突,此时我们根据线性探测再散列法来处理这个冲突,探测下一个位置6, 6这个位置上已经存在关键字30则继续增加步长1,因此现在的新地址应为7,位置7上没有关键字,放入即可,到此冲突已经解决;第六个key 9,它的地址是6,因此放到散列表的数组下表为6的位置,但这个位置上已经有关键字30,遇到了冲突,探测下一个位置7, 7这个位置上已经存在关键字18则继续增加步长1,因此现在的新地址应为8,位置8上没有关键字,放入即可;第七个key 14,它的地址是0,因此放到散列表的数组下表为0的位置,但这个位置上已经有关键字7,遇到了冲突,探测下一个位置1, 位置1上没有关键字,放入即可;到这一步所有关键字均已填入,散列表已经构造完成,如表2所示。

双重散列探查法的计算公式

双重散列探查法的计算公式

双重散列探查法的计算公式平方取中法具体方法:先通过求关键字的平方值扩大相近数的差别,然后根据表长度取中间的几位数作为散列函数值。

又因为一个乘积的中间几位数和乘数的每一位都相关,所以由此产生的散列地址较为均匀。

例:将一组关键字(0100,0110,1010,1001,0111)平方后得(0010000,0012100,1020100,1002001,0012321)若取表长为1000,则可取中间的三位数作为散列地址集:(100,121,201,020,123)。

相应的散列函数用C实现很简单:int Hash(int key){ //假设key是4位整数key*=key;key/=100;//先求平方值,后去掉末尾的两位数return key%1000;//取中间三位数作为散列地址返回除余法该方法是最为简单常用的一种方法。

它是以表长m来除关键字,取其余数作为散列地址,即h(key)=key%m该方法的关键是选取m。

选取的m应使得散列函数值尽可能与关键字的各位相关。

m最好为素数。

若选m是关键字的基数的幂次,则就等于是选择关键字的最后若干位数字作为地址,而与高位无关。

于是高位不同而低位相同的关键字均互为同义词。

若关键字是十进制整数,其基为10,则当m=100时,159,259,359,…,等均互为同义词。

相乘取整法该方法包括两个步骤:首先用关键字key乘上某个常数A(0<A<1),并抽取出key.A的小数部分;然后用m乘以该小数后取整。

即:该方法最大的优点是选取m不再像除余法那样关键。

比如,完全可选择它是2的整数次幂。

虽然该方法对任何A的值都适用,但对某些值效果会更好。

Knuth建议选取该函数的C代码为:int Hash(int key){double d=key *A;//不妨设A和m已有定义return (int)(m*(d-(int)d));//(int)表示强制转换后面的表达式为整数}。

双重散列探查法的计算公式

双重散列探查法的计算公式

双重散列探查法的计算公式1. 线性探测法如果我们能够预测将要存入表中元素的数目,而且我们有足够的内存空间可以容纳带有空闲空间的所有关键字,那么使用链地址法是不值得的。

我们依靠空的存储空间解决冲突:设计表长M大于元素数目N,开放地址法,最简单的开放地址法是线性探测法:初始化该符号表的实现将元素保存到大小是元素个数两倍的散列表中。

void HashTableInit(int max){N = 0;M = 2*max;hash_table = new Item[M];for(int i = 0; i < M; i++)hash_table[i] = NULLItem;插入(1)当冲突发生时,即准备插入的位置已被占用,我们检查表中的下一个位置,(2)如果下一个位置也被占用,继续检查下一个,知道遇到一个空位,然后将其插入在搜索时:void HashTableInsert(Item item){int hash_key = Hash(GetKey(item), M);while (hash_table[hash_key] != NULLItem) {hash_key = (hash_key+1) % M;}hash_table[hash_key] = item;N++;}搜索我们将检查表中是否存在与搜索关键字匹配的元素成为探测。

线性探测法的特点是每次探测有3种可能结果:(1)搜索命中(当前位置上的元素关键字与搜索关键字匹配,停止搜索),(2)搜索失败(搜索位置为空,停止搜索),(3)不匹配(搜索位置非空,但是不匹配,继续搜索下一位置)。

Item HashT abelSearch(KeyItem v){int hash_key = Hash(v, M);//遇到空位置,搜索失败while (hash_table[hash_key] != NULLItem) {if(eq(GetKey(hash_table[hash_key]), v)) //搜索命中break;hash_key = (hash_key+1) % M; //不匹配}return hash_table[hash_key];}删除线性探测表中的删除,仅仅移走删除关键字对应的元素时不够的。

线性探测再散列

线性探测再散列

线性探测再散列https:///qq_19446965/article/details/102290770哈希表⼜称散列表。

哈希表存储的基本思想是:以数据表中的每个记录的关键字 k为⾃变量,通过⼀种函数H(k)计算出函数值。

把这个值解释为⼀块连续存储空间(即数组空间)的单元地址(即下标),将该记录存储到这个单元中。

在此称该函数H为哈希函数或散列函数。

按这种⽅法建⽴的表称为哈希表或散列表。

处理冲突的⽅法:开放寻址法:Hi=(H(key) + di) MOD m, i=1,2,…, k(k<=m-1),其中H(key)为散列函数,m为散列表长,di为增量序列,可有下列三种取法:1.di=1,2,3,…, m-1,称线性探测再散列;2.di=1^2, -1^2, 2^2,-2^2, 3^2, …, ±(k)^2,(k<=m/2)称⼆次探测再散列;3.di=伪随机数序列,称伪随机探测再散列。

再散列法:Hi=RHi(key), i=1,2,…,k. RHi均是不同的散列函数,即在同义词产⽣地址冲突时计算另⼀个散列函数地址,直到冲突不再发⽣,这种⽅法不易产⽣“聚集”,但增加了计算时间;链地址法(拉链法):将所有关键字为同义词的记录存储在同⼀线性链表中;设哈希表长为14,哈希函数是H(key)=key%11,表中已有数据的关键字为15,38,61,84共四个,现要将关键字为49的结点加到表中,⽤⼆次探测再散列法解决冲突,则放⼊的位置是( ) 【南京理⼯⼤学 2001 ⼀、15 (1.5分)】A.8 B.3 C.5 D.9答案为A,为什么我计算出来是D呢?我的计算步骤如下:15,38,61,84⽤哈希函数H(key)=key%11计算后得地址:4,5,6,749计算后为5,发⽣冲突.⽤⼆次探测再散列法解决冲突:1:(key+1^2)%11=(49+1)%11=6,仍然发⽣冲突.2:(key-1^2)%11=(49-1)%11=4,仍然发⽣冲突.3:(key+2^2)%11=(49+4)%11=9,不再发⽣冲突.得出结果为D。

散 列 法

散 列 法

H(k4)=3,
总记录个数为5,开辟的一维数组长度可以比实
际用的存储单元多一些,取m=8。
查找
图8.8 开放地址的线性探测
查找
二次探测法
二次探测法的基本思想是:生成的探查地址 序列不是连续的,而是跳跃式的。二次探测 法对应的探查地址序列的计算公式为: di = (H(k)+i) mod m
其中i=12,-12,22,-22,……j2,-j2,(j≤m/2)。
查找
图8.7 散列法
可能由不同的关键字计算出相同的散列函数 值来,例如此例中h(1)和h(15)都等于2,也 就是遇到了不同记录占用同一地址单元的情 况,这种情况称为发生了冲突(collision)。
查找
散列是一种重要的存储方法,又是一种查找方 法。
应用散列法存储记录的过程是对每个记录的关 键字进行散列函数的运算,计算出该记录存储 的地址,并将记录存入此地址中。
查找
图8.10 链接表法
查找
1.4 散列法的查找运算
散列表的目的主要是用于快速查找。
在建表时采用何种散列函数及何种解决冲突的 办法,在查找时,也采用同样的散列函数及解 决冲突的办法。假设给定的值为k,根据建表 时设定的散列函数H,计算出散列地址H(k), 如果表中该地址单元为空,则查找失败;否则 将该地址中的关键字值与给定值k比较,如果 相等则查找成功,否则按建表时设定的处理冲 突的方法找下一个地址,如此反复下去,直到 某个地址单元为空(查找失败)或与关键字值 比较相等(查找成功)为止。
当在闭散列表上发生冲突时,必须按某种方法 在散列表中形成一个探查地址序列,沿着这个 探查地址序列在数组中逐个查找,直到碰到无 冲突的位置为止,并放入记录。
查找

双重散列探查法的计算公式

双重散列探查法的计算公式

双重散列探查法的计算公式一、散列表的由来?1.散列表来源于数组,它借助散列函数对数组这种数据结构进行扩展,利用的是数组支持按照下标随机访问元素的特性。

2.需要存储在散列表中的数据我们称为键,将键转化为数组下标的方法称为散列函数,散列函数的计算结果称为散列值。

3.将数据存储在散列值对应的数组下标位置。

二、如何设计散列函数?总结3点设计散列函数的基本要求1.散列函数计算得到的散列值是一个非负整数。

2.若key1=key2,则hash(key1)=hash(key2)3.若key≠key2,则hash(key1)≠hash(key2)正是由于第3点要求,所以产生了几乎无法避免的散列冲突问题。

三、散列冲突的解放方法?1.常用的散列冲突解决方法有2类:开放寻址法(open addressing)和链表法(chaining)2.开放寻址法①核心思想:如果出现散列冲突,就重新探测一个空闲位置,将其插入。

②线性探测法(Linear Probing):插入数据:当我们往散列表中插入数据时,如果某个数据经过散列函数之后,存储的位置已经被占用了,我们就从当前位置开始,依次往后查找,看是否有空闲位置,直到找到为止。

查找数据:我们通过散列函数求出要查找元素的键值对应的散列值,然后比较数组中下标为散列值的元素和要查找的元素是否相等,若相等,则说明就是我们要查找的元素;否则,就顺序往后依次查找。

如果遍历到数组的空闲位置还未找到,就说明要查找的元素并没有在散列表中。

删除数据:为了不让查找算法失效,可以将删除的元素特殊标记为deleted,当线性探测查找的时候,遇到标记为deleted的空间,并不是停下来,而是继续往下探测。

结论:最坏时间复杂度为O(n)③二次探测(Quadratic probing):线性探测每次探测的步长为1,即在数组中一个一个探测,而二次探测的步长变为原来的平方。

④双重散列(Double hashing):使用一组散列函数,直到找到空闲位置为止。

8.3.3 冲突处理技术之二次探查法

8.3.3 冲突处理技术之二次探查法

散列表Content散列技术简介1常见散列函数2冲突处理技术3PART THREEC 二次探查法线性探查法的缺点:易使元素在表中连成一片(线性聚集),探查次数增加,影响搜索效率改进方法:二次探查法二次探查法的探查序列h(key), h1(key), h2(key), …, h2i-1(key), h2i(key),…探查序列由下列函数得到h2i-1(key)=(h(key)+i2) % Mh2i(key)=(h(key)-i2) % Mi=1,2,…,(M-1)/2二次探查法的探查序列i=1h 1(key)=(h(key)+12) % Mh 2(key)=(h(key)-12) % M i=2h 3(key)=(h(key)+22) % M h 4(key)=(h(key)-22) % M i=3h 5(key)=(h(key)+32) % M h 6(key)=(h(key)-32) % M i=4h 7(key)=(h(key)+42) % M h 8(key)=(h(key)-42) % Mi=5h 9(key)=(h(key)+52) % M h 10(key)=(h(key)-52) % M探查序列由下列函数得到h 2i-1(key)=(h(key)+i 2) % M h 2i (key)=(h(key)-i 2) % Mi =1,2,…,(M -1)/2注意负数的取模计算问题i=1h1(key)=(h(key)+12) % M h2(key)=(h(key)-12) % M i=2h3(key)=(h(key)+22) % M h4(key)=(h(key)-22) % M i=3h5(key)=(h(key)+32) % M h6(key)=(h(key)-32) % M i=4h7(key)=(h(key)+42) % M h8(key)=(h(key)-42) % M i=5h9(key)=(h(key)+52) % M h10(key)=(h(key)-52) % Mh(40)=7i=1h1(40)=(7+12) % 11 = 8h2(40)=(7-12) % 11 = 6 i=2h3(40)=(7+22) % 11 = 0h4(40)=(7-22) % 11 = 3 i=3h5(40)=(7+32) % 11 = 5h6(40)=(7-32) % 11 = 9 i=4h5(40)=(7+42) % 11 = 1h6(40)=(7-42) % 11 = 2 i=5h5(40)=(7+52) % 11 = 10 h6(40)=(7-52) % 11 = 4散列函数h(key)=key % 11 i最大为5常见错误h(key), h1(key), h2(key), …, h2i-1(key), h2i(key),…探查序列由下列函数得到h2i-1(key)=(h(key)+i2) % M h2i(key)=(h(key)-i2) % Mi=1,2,…,(M-1)/2 ⚫先减后加⚫漏掉基地址⚫取模计算错误插入35h(key)=35%11=2h 1(key)=(h(key)+12)%11=3h 2(key)=(h(key)-12)%11=1123456789102480156535插入13h(key)=13%11=2h 1(key)=(h(key)+12)%11=3h 2(key)=(h(key)-12)%11=1h 3(key)=(h(key)+22)%11=612345678910352480156513h(key)=13%11=2h 1(key)=(h(key)+12)%11=3h 2(key)=(h(key)-12)%11=1h 3(key)=(h(key)+22)%11=612345678910352480156513h(key)=35%11=2h 1(key)=(h(key)+12)%11=3h 2(key)=(h(key)-12)%11=1二次探查法能改善“线性聚集”但是同义词会有相同的探查序列,产生“二次聚集”END NEXT:双散列法。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

计算公式:
计算公式是人们在研究自然界物与物之间时发现的一些联系,并通过一定的方式表达出来的一种表达方法。

是表征自然界不同事物之数量之间的或等或不等的联系,它确切的反映了事物内部和外部的关系,是我们从一种事物到达另一种事物的依据,使我们更好的理解事物的本质和内涵。

二次再散列法:
散列(Hashing)是计算机科学中一种对资料的处理方法,通过某种特定的函数/算法(称为散列函数/算法)将要检索的项与用来检索的索引(称为散列,或者散列值)关联起来,生成一种便于搜索的数据结构(称为散列表)。

二次再散列法是指第一次散列产生哈希地址冲突,为了解决冲突,采用另外的散列函数或者对冲突结果进行处理的方法。

散列表:
设所有可能出现的关键字集合记为U(简称全集)。

实际发生(即实际存储)的关键字集合记为K(|K|比|U|小得多)。

散列方法是使用函数h将U映射到表T[0..m-1]的下标上(m=O(|U|))。

这样以U中关键字为自变量,以h为函数的运算结果就是相应结点的存储地址。

从而达到在O(1)时间内就可完成查找。

其中:
① h:U→{0,1,2,…,m-1} ,通常称h为散列函数(Hash Function)。

散列函数h的作用是压缩待处理的下标范围,使待处理
的|U|个值减少到m个值,从而降低空间开销。

② T为散列表(Hash Table)。

③ h(Ki)(Ki∈U)是关键字为Ki结点存储地址(亦称散列值或散列地址)。

④ 将结点按其关键字的散列地址存储到散列表中的过程称为散列(Hashing)
冲突:
两个不同的关键字,由于散列函数值相同,因而被映射到同一表位置上。

该现象称为冲突(Collision)或碰撞。

发生冲突的两个关键字称为该散列函数的同义词(Synonym)。

安全避免冲突的条件
最理想的解决冲突的方法是安全避免冲突。

要做到这一点必须满足两个条件:
①其一是|U|≤m
②其二是选择合适的散列函数。

这只适用于|U|较小,且关键字均事先已知的情况,此时经过精心设计散列函数h有可能完全避免冲突。

冲突不可能完全避免
通常情况下,h是一个压缩映像。

虽然|K|≤m,但|U|>m,故无论怎样设计h,也不可能完全避免冲突。

因此,只能在设计h时尽可能使冲突最少。

同时还需要确定解决冲突的方法,使发生冲突的同义词能够存储到表中。

影响冲突的因素
冲突的频繁程度除了与h相关外,还与表的填满程度相关。

设m和n分别表示表长和表中填人的结点数,则将α=n/m定义为散列表的装填因子(Load Factor)。

α越大,表越满,冲突的机会也越大。

通常取α≤1。

对于大多数应用程序来说,装填因子为0.75是比较合理的。

相关文档
最新文档