C语言--哈希表

哈希表介绍

        在面前讨论的各种结构(线性表、树)中,记录在结构中的相对位置是随机的,和记录的关键字之间不存在确定的关系。因此,在结构中查找记录时需进行一系列和关键字的比较。这一类查找方法建立在“比较”的基础上。在顺序查找时,比较的结果为“=”与“≠”两种可能;在折半查找、二叉排序树查找,比较的结果为“<”、“=”和“>”三种可能。查找的效率依赖于查找过程中所进行的比较次数。

哈希表的概念

        在查找时,我们理想的情况是希望不经过任何比较,一次存取便能得到所查记录,那就必须在记录的储存位置和它的关键字之间建立一个确定的对应关系f,使每个关键字和结构中一个唯一的储存位置相对应。因而在查找时,只要根据这个对应关系f找到给定值k得像f(k)。若结构中存在关键字和k相等的记录,则必定在f(k)的储存位置上,由此,不需要进行比较便可直接取得所查记录。在此,我们称这个对应关系f为散列函数,又称为哈希(Hash)函数,按这个思想采用散列技术将记录存储在一块连续的存储空间中,这块连续存储空间称为散列表或哈希表

哈希函数的构造方法

        

构造哈希函数的方法撒很多。在介绍各种方法之前,首先需要明确什么是“好”的哈希函数。

若对于关键字集合中的任何一个关键字,经哈希函数映像到地址集合中任何一个地址的概率是相等的。则称此类哈希函数为均匀的(Uniform)哈希函数。换句话说,就是是关键字经过哈希函数得到一个“随机的地址”,以便使一组关键字的哈希地址均匀分布在整个地址区间中,从而减少冲突。

常用的构造哈希函数的方法有:

直接定址法:

         取关键字或关键字的某个线性函数值为哈希地址。即:

        H(Key)=key或(key)=a*key+b

        其中a和b为常数(这种哈希函数叫做自身函数)。

数字分析法:

         假设关键字是以r为基的数(如:以10为基的十进制数)。并且哈希表中可能出现的关键字都是事先知道的,则可取关键字的若干数位组成哈希地址。例如有80个记录,其关键字为8位十进制数。假设哈希的表长为10010,则可取两位十进制数组成哈希地址。取哪两位?原则是使得到的哈希地址尽量避免产生冲突,则需从分析这80个关键字着手。假设这80个关键字中的一部分如下所列: C语言--哈希表_第1张图片

 对关键字全体的分析中我们发现第1,2 位都是“8,1”,第三位3或4, 第8位只可能取2,5,7,因此这四位数都不可取。由于中间的四位数可看成是近乎随机的,因此可取其中任意两位,获取其中两位与另外两位的叠加求和后舍去进位作为哈希地址。

平方取中法:

        取关键字平方后的中间几位为哈希地址。这是一种较常见的构造哈希函数的方法。通常在选定哈希函数时不一定能知道关键字的全部情况,取其中哪几位也不一定合适,而一个数平方后的中间几位数可以取出做哈希地址,由此使随机分布的关键字得到的哈希地址也是随机的。取的位数由表长决定。

例如:关键字是1234,那么它的平方就是1522756,再抽取中间的3位就是227,用作散列地址。再比如关键字是4321,那么它的平方就是18671041,抽取中间的3位就可以是671,也可以是710,用作散列地址。平方取中法比较适合于不知道关键字的分布,而位数又不是很大的情况。

除留余数法:

        取关键字被某个不大于哈希表表长m的数p除后所得余数为哈希地址。即

H(key)=key MOD p p< m

这是一种最简单,也最常用的构造哈希函数的方法。他不仅可以对关键字直接取模(MOD),也可以在折迭、平方取中等运算之后取摸。值得注意的是,在使用除留余数法时,对p的选择很重要。若p选的不好,容易产生同义词。

等。

哈希表的查找和分析

        在哈希表上进行查找的过程跟哈希造表过程基本一致,给定K值,根据造表时设计的哈希函数计算出哈希地址,若此位置上没有记录,则查找不成功;否则比较关键字若与给定的关键字相同,则查找成功;否则根据造表时处理冲突的方法找“下一地址”,直至哈希表中某个位置为空,或者表中所填记录的关键字与给定的关键字相等为止。

已知如图所示一组关键字按哈希函数H(key)=key MOD 13和线性探测处理冲突,构造所得的哈希表。

C语言--哈希表_第2张图片  

 

例如查找关键字84,H(84)=6,去6查看发现该单元格不空,但是不等于84,采用线性探测处理冲突则去下一位位置7查找,发现不空也不等于84,则再线性探测去8单元格找,不空恰好等于84,则查找成功,查找次数为3。

其他元素依次类推,可得到平均的查找长度(ASL):

 

综上所述,一般情况,查找的平均长度与三个因素相关:

1、哈希函数

2、处理冲突的方法

3、装填因子

哈希表的装填因子定义为:

C语言--哈希表_第3张图片

 α的值越小,发生冲突的概率越小,反之α越大,表中填入的记录越多,在填入的时候发生冲突的可能性就越大,在进行查找时候,查找的次数也就越多。

你可能感兴趣的:(c语言,数据结构,哈希算法)