一、哈希表

1、概念

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

2、散列存储的基本思路

以数据中每个元素的关键字K为自变量,通过散列函数H(k)计算出函数值,以该函数值作为一块连续存储空间的的单元地址,将该元素存储到函数值对应的单元中。

3、哈希表查找的时间复杂度

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

二、常用的哈希函数

1.   直接寻址法

取关键字或者关键字的某个线性函数值作为哈希地址,即H(Key)=Key或者H(Key)=a*Key+b(a,b为整数),这种散列函数也叫做自身函数.如果H(Key)的哈希地址上已经有值了,那么就往下一个位置找,知道找到H(Key)的位置没有值了就把元素放进去.

2.   数字分析法

分析一组数据,比如一组员工的出生年月,这时我们发现出生年月的前几位数字一般都相同,因此,出现冲突的概率就会很大,但是我们发现年月日的后几位表示月份和具体日期的数字差别很大,如果利用后面的几位数字来构造散列地址,则冲突的几率则会明显降低.因此数字分析法就是找出数字的规律,尽可能利用这些数据来构造冲突几率较低的散列地址.

3.   平方取中法

取关键字平方后的中间几位作为散列地址.一个数的平方值的中间几位和数的每一位都有关。因此,有平方取中法得到的哈希地址同关键字的每一位都有关,是的哈希地址具有较好的分散性。该方法适用于关键字中的每一位取值都不够分散或者较分散的位数小于哈希地址所需要的位数的情况。

4.   折叠法

折叠法即将关键字分割成位数相同的几部分,最后一部分位数可以不同,然后取这几部分的叠加和(注意:叠加和时去除进位)作为散列地址.数位叠加可以有移位叠加和间界叠加两种方法.移位叠加是将分割后的每一部分的最低位对齐,然后相加;间界叠加是从一端向另一端沿分割界来回折叠,然后对齐相加.

5.   随机数法

选择一个随机数,去关键字的随机值作为散列地址,通常用于关键字长度不同的场合.

6.   除留余数法

取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址.即H(Key)=Key MOD p,p<=m.不仅可以对关键字直接取模,也可在折叠、平方取中等运算之后取模。对p的选择很重要,一般取素数或m,若p选得不好,则很容易产生冲突。一般p取值为表的长度tableSize。

三、哈希冲突的处理方法

1、开放定址法——线性探测

线性探测法的地址增量di = 1, 2, ... , m-1,其中,i为探测次数。该方法一次探测下一个地址,知道有空的地址后插入,若整个空间都找不到空余的地址,则产生溢出。

线性探测容易产生“聚集”现象。当表中的第i、i+1、i+2的位置上已经存储某些关键字,则下一次哈希地址为i、i+1、i+2、i+3的关键字都将企图填入到i+3的位置上,这种多个哈希地址不同的关键字争夺同一个后继哈希地址的现象称为“聚集”。聚集对查找效率有很大影响。

2、开放地址法——二次探测

二次探测法的地址增量序列为 di = 12, -12, 22, -22,… , q2, -q2 (q <= m/2)。二次探测能有效避免“聚集”现象,但是不能够探测到哈希表上所有的存储单元,但是至少能够探测到一半。

3、链地址法

链地址法也成为拉链法。其基本思路是:将所有具有相同哈希地址的而不同关键字的数据元素连接到同一个单链表中。如果选定的哈希表长度为m,则可将哈希表定义为一个有m个头指针组成的指针数组T[0..m-1],凡是哈希地址为i的数据元素,均以节点的形式插入到T[i]为头指针的单链表中。并且新的元素插入到链表的前端,这不仅因为方便,还因为经常发生这样的事实:新近插入的元素最优可能不久又被访问。

链地址法特点

(1)拉链法处理冲突简单,且无堆积现象,即非同义词决不会发生冲突,因此平均查找长度较短; 
(2)由于拉链法中各链表上的结点空间是动态申请的,故它更适合于造表前无法确定表长的情况; 
(3)开放定址法为减少冲突,要求装填因子α较小,故当结点规模较大时会浪费很多空间。而拉链法中可取α≥1,且结点较大时,拉链法中增加的指针域可忽略不计,因此节省空间; 
(4)在用拉链法构造的散列表中,删除结点的操作易于实现。只要简单地删去链表上相应的结点即可。而对开放地址法构造的散列表,删除结点不能简单地将被删结点的空间置为空,否则将截断在它之后填人散列表的同义词结点的查找路径。这是因为各种开放地址法中,空地址单元(即开放地址)都是查找失败的条件。因此在用开放地址法处理冲突的散列表上执行删除操作,只能在被删结点上做删除标记,而不能真正删除结点。

四、哈希表的装填因子

装填因子 = (哈希表中的记录数) /  (哈希表的长度)

装填因子是哈希表装满程度的标记因子。值越大,填入表中的数据元素越多,产生冲突的可能性越大。

五、不同处理冲突的平均查找长度

例:

假设散列表的长度是13,三列函数为H(K) = k % 13,给定的关键字序列为{32, 14, 23, 01, 42, 20, 45, 27, 55, 24, 10, 53}。分别画出用线性探测法和拉链法解决冲突时构造的哈希表,并求出在等概率情况下,这两种方法的查找成功和查找不成功的平均查找长度。

(1)线性探测法:

查找成功时的查找次数等于插入元素时的比较次数, 查找成功的平均查找长度为:
ASL = (1+2+1+4+3+1+1+3+9+1+1+3)/12 = 2.5

查找成功时的查找次数:第n个位置不成功时的比较次数为,第n个位置到第1个没有数据位置的距离:如第0个位置取值为1,第1个位置取值为2.

查找不成功的平均查找次数为:

ASL = (1+2+3+4+5+6+7+8+9+10+11+12)/ 13 = 91/13

(2)链地址法

查找成功时的平均查找长度:

ASL = (1*6+2*4+3*1+4*1)/12 = 7/4

查找不成功时的平均查找长度:

ASL = (4+2+2+1+2+1)/13

注意:查找成功时,分母为哈希表元素个数,查找不成功时,分母为哈希表长度。

原文地址:https://blog.csdn.net/u011080472/article/details/51177412

【数据结构】哈希表——线性探测法、链地址法、查找成功、查找不成功的平均长度相关推荐

  1. 【数据结构】人名查询哈希表设计(链地址法)

    文章目录 核心代码 链表节点定义 链地址法处理冲突 查询函数 完整代码下载 核心代码 哈希表使用「链地址法」解决地址冲突的方式,其数据结构就采用 数组+链表 ,数组的每一个元素都是一个链表节点,当地址 ...

  2. C++数据结构——小明的通讯录(哈希表线性探测法)

    小明的通讯录 小明上中学了,为了方便和家里以及同学联系,爸爸终于给小明买了一台手机.该手机的存储容量可以扩充,因此,可以存储的电话号码数量没有限制. 小明的手机有一个特殊的功能,对于打进或拨出的电话, ...

  3. 数据结构——哈希表的详解与实现

    数据结构--哈希表(HashTable) 1.前言 ​ 当我们频繁的查找数据中的某个元素时,我们通常会选择数组来存放数据,因为数组的的内存是连续的,可以直接通过下标访问数据,但是它添加和删除数据比较麻 ...

  4. 哈希表:线性探测法和链地址法求查找成功与不成功的平均查找长度

    哈希表:线性探测法和链地址法求查找成功与不成功的平均查找长度 了解ASL的公式 线性探测法求ASL 链地址法求ASL 了解ASL的公式 查找成功时:ASL =1n\frac{1}{n}n1​ ∑i=1 ...

  5. SWUST OJ 1012: 哈希表(链地址法处理冲突)

    1012: 哈希表(链地址法处理冲突) 题目描述 采用除留余数法(H(key)=key %n)建立长度为n的哈希表,处理冲突用链地址法.建立链表的时候采用尾插法. 输入 第一行为哈西表的长度m: 第二 ...

  6. (7)哈希表的链地址法实现

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

  7. c语言链地址法构造哈希表,链地址处理法构造简单哈希表

    链地址法:将所有关键字为同义词的记录保存在一个线性链表中(拉链法) 设某哈希函数产生的哈希地址在区间[0,12]上,则创建指针数组add[12],其中每个元素都是一个单项链表的头结点(有值). 由于仅 ...

  8. 哈希查找解决地址冲突的两种最常见方法(线性探测再散列,链地址法)C++实现

    哈希查找解决地址冲突的两种最常见方法(线性探测再散列,链地址法)C++实现 参考文章: (1)哈希查找解决地址冲突的两种最常见方法(线性探测再散列,链地址法)C++实现 (2)https://www. ...

  9. Java解决Hash(散列)冲突的四种方法--开放地址法(线性探测,二次探测,伪随机探测)、链地址法、再哈希、建立公共溢出区

    Java解决Hash(散列)冲突的四种方法--开放地址法(线性探测,二次探测,伪随机探测).链地址法.再哈希.建立公共溢出区 参考文章: (1)Java解决Hash(散列)冲突的四种方法--开放地址法 ...

最新文章

  1. Embarcadero Dev C++ 中文输出乱码
  2. 5.15 pymysql 模块
  3. .net 连mysql代码_.net连接常用的数据库代码
  4. windows Pycharm 常用快捷键
  5. python 累加器_Python编程第5课:累加器,变量与赋值进阶练习
  6. mysql的root用户密码_MySQL的root用户密码忘了 , 该怎么办?
  7. Object-C中方法
  8. 操作系统(15)-Linux的用户权限
  9. Leetcode每日一题:155.min-stack(最小栈)
  10. 1051. 复数乘法 (15)-PAT乙级真题
  11. pdf.js跨域加载文件
  12. SAP SD pricing condition技术在系统里的一些练习
  13. OptiX OSN3500
  14. htc magic 刷机
  15. 计算机CPU核的位数,如何查cpu位数
  16. java做橡皮擦效果_Android自定义橡皮擦效果
  17. Tensorflow图像识别-2
  18. 【潍坊seo公司】普通人都能学会的SEO,让你打破网络营销瓶颈
  19. csgo人机指令_csgo人机指令大全
  20. 哪个系统检测论文比较好?

热门文章

  1. 心里藏着小星星,生活才能亮晶晶
  2. pde与波长 sipm 关系_SiPM应用于LiDAR:为何要先解决延时脉冲,而不是先提升PDE?...
  3. DSN: Deep Subspace Clustering Networks
  4. Typescript 史上最强学习入门文章 ( 2w 字)
  5. 慕课网的python2020_2020中.国大学慕课Python开发入门答案
  6. 他被称为中国第一程序员,一人之力单挑微软,如今拜入武当修道(转载)
  7. 2021全国大学生数学建模竞赛A题思路
  8. 运用简单的超市购物车系统,理解重写equals、hashcode的意义
  9. Oracle索引梳理系列(六)- Oracle索引种类之函数索引
  10. 《A fast and elitist multiobjective genetic algorithm: NSGA-II》阅读笔记