散列表

        哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。映射函数叫做散列函数,存放记录的数组叫做散列表。

装填因子

        关键字个数 / 表长

处理冲突

        一般来说冲突不可避免的,只能尽可能地减少冲突的发生。在建立Hash表的时候必须进行冲突处理。
        下面主要介绍线性探测法:也是一种比较常用的处理冲突的方法(但是极易产生堆积问题)

  • 线性探测法 即从发生冲突的地址(记做d)开始,依次探查d的下一个地址,直至找到一个空位置为止。记住这句话。查找时若查到空位置还没有找到需要查找的元素则说明不在列表中,结合前一句话理解一下,还是比较容易理解的。这个为后面计算查找失败的平均长度提供了计算思路。
  • 链地址法 通过单链表将关键字连接起来,利用这种方法不会产生堆积问题。但是所谓的堆积问题,并不能完全通过利用单链表法来避免。毕竟并不是适用于任何问题,在能够利用链地址法不能解决冲突的问题,也许利用线性探测法可以有着不错的效果。

性能分析

即本文的主要内容,查找成功与查找失败的分析。

  • 查找成功平均查找长度即找到表中已有表项的平均比较次数
  • 查找失败平均查找长度即找不到待查的表项但能找到插入位置的平均比较次数

平均查找长度的计算

直接以题目来理解会比较快些:

        现有长度为11 且初始为空的散列表HT,散列函数H(key) = key % 7,采用线性探查法解决冲突。将关键字序列87,40,30,6,11,22,98,20 依次插入HT后,HT的查找失败的平均长度是多少呢? 查找成功的平均查找长度又是多少呢?
        ① 首先,通过散列函数并且利用线性探测法给他们每个字划分好自己的位置;
        ② 记录每个字冲突的次数,后面在计算查找成功的平均长度会用到;
        ③ 查找失败计算每个查找失败对应地址的查找次数,即从所查位置开始往后查直至查到空位置位置;
        ④ 其实,后面熟悉过程之后,在列出下面的每个关键字对应地址的表格之后就可以秒出答案;

注意事项 查找失败时对应的地址在这个题目,只能是7 即 0~6 ;

ASL 查找失败= (9 + 8 + 7 + 6 + 5 + 4 + 3 )/ 7 = 6

ASL 查找成功= (1 + 1 + 1 + 1 + 1 + 1 + 1 + 2)/ 8 = 9 / 8

散列地址012345678910
关键字982230871140620
冲突次数00000001

OK,上面把例子说完了,可以再看看下面这个题目,来测试下是否理解了上面的那些需要注意的点。
        将关键字序列(7,8,30,11,18,9,14)散列存储到散列表中。散列表的存储空间是从0开始的一维数组,散列函数为H(key) = (3*key)mod 7,处理冲突采用线性探测法,要求装填因子为0.7。
        (1)画出所构造的散列表。
        (2)分别计算等概率情况下的查找成功和不成功的平均查找长度。(12/7 和 18/7

(1)数组大小 = 7 / 0.7 = 10

散列地址0123456789
关键字71481130189

(2)
        ①查找成功时

散列地址0123456789
关键字71481130189
冲突次数0100022
比较次数1211133

        ASL 查找成功= (1 + 2 + 1 + 1 + 1 + 3 + 3 )/ 7 = 12 / 7
        ②查找失败时

散列地址0123456789
关键字71481130189
比较次数3212154

        ASL 查找失败= (3 + 2 + 1 + 2 + 5 + 4)/ 7 = 18 / 7

【总结】简单吧,主要就是查找失败时除以的分母是 mod 后面的那个数,而不是关键字的个数。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐