哈希表的简单介绍

哈希表的概念

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

哈希表查找的时间复杂度

哈希表存储的是键值对,其查找的时间复杂度与元素数量的多少无关,哈希表在查找元素的时候通过计算哈希码值来定位元素的位置从而直接访问元素的,因此哈希表查找的时间复杂度为O(1)。

当向哈希表
    插入元素时:根据待插入元素的关键码,计算出该元素的存储位置,并进行存放。
查找元素时:对元素的关键码进行同样的计算,把求得的函数值当做元素的存储位置,
在结构中,按此位置取元素比较,若关键码相等,则搜索成功。
常见的哈希函数
  • 直接定制法  

    取关键字的某个线性函数为散列地址:Hash(Key)= A*Key + B  
    优点:简单、均匀  
    缺点:需要事先知道关键字的分布情况  
    适合查找比较小且连续的情况  
    面试题:找出一个字符串中第一个只出现一次的字符,要求:时间复杂度O(N),空间复杂度O(1)

  • 除留余数法

    设散列表中允许的地址数为m,取一个不大于m,但最接近或者等于m的质数p作为除数,按照哈希函数:Hash(key) = key % p(p<=m),将关键码转换成哈希地址  

  • 折叠法
  • 数学分析法
  • 随机数法
  • 平方取中法
哈希冲突

即不同关键字通过相同哈希哈数计算出相同的哈希地址,该种现象称为哈希冲突或哈希碰撞。把具有不同关键码而具有相同哈希地址的数据元素称为“同义词”。

那么我们如何解决哈希冲突呢?
常用的解决哈希冲突的方法有两种:开散列法闭散列法

闭散列
闭散列:也叫开放地址法,当发生哈希冲突时,如果哈希表未被装满,说明在哈希表中必然还有空位置,那么可以把key存放到表中“下一个” 空位中去。

常用的探测方法有 :线性探测、二测谈探测等。

负载因子:
散列表的负载因子定义为:a = 填入表中的元素个数 / 散列表长度对于开放定址法,
散列荷载因子是重要的影响因素,应该严格限制在0.7~0.8,超过0.8,cpu缓冲不命
中按指数曲线上升。

开散列

开散列法又叫链地址法(开链法)。
开散列法:首先对关键码集合用散列函数计算散列地址,具有相同地址的关键码归于同一子集合,每一个子集合称为一个桶,各个桶中的元素通过一个单链表链接起来,各链表的头结点存储在哈希表中。

通常,每个桶对应的链表结点都很少,将n个关键码通过某一个散列函数,存放到散列表中的m个桶中,那么每一个桶中链表的平均长度为 n / m 。以搜索平均长度为 n / m 的链表代替了搜索长度为 n 的顺序表,搜索效率快的多。

接下来我们将实现一下开散列以及闭散列,具体代码请参考我的另一篇博客:
哈希表具体实现

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章