### 一、基本概念 数据的存储位置与关键字之间存在对应关系(hash函数),简言之:数据存储的位置与hash函数计算结果相关 Loc(i)=H(key) 散列方法:根据hash函数计算元素存储位置,在查找时也按照相同hash函数进行计算并查找 哈希函数:计算hash值的函数 哈希表:按照hash值构造的表 哈希冲突:不同的Key计算出来的hash值相同 同义词:通过hash函数计算出来值相同的key ![[微信截图_20221219203714.png]] ### 二、hash函数构造 ##### 使用哈希表要解决2个问题: 1. 构造好的哈希函数 1. 所选函数尽可能简单,以便提高转换效率 2. 所选函数对关键码计算出的地址,应在散列地址集中致均匀分布,以减少空间浪费 2. 制定一个好的解决冲突的方案 查找时,如果从哈希函数计算出的地址中查不到关键码,则应当依据解决冲突的规则,有规律地查询其他相关单元 ##### 构造哈希函数考虑的因素 + 执行速度(即计算哈希函数所需时间) + 关键字长度 + 哈希表大小 + 关键字的分布情况 + 查找频率 ##### 根据元素集合的特性构造: 一、N个数据源仅占用n个地址,虽然哈希表查找是以空间换时间,但仍希望散列的地址空间尽量小。 二、无论用什么方法存储,目的都是尽量均匀地存放元素,以避免冲突 #### 构造的6种方法 + 直接定址法:H(key)=key或H(key)=a*key+b 其中,a和b是常数,它适合关键字的分布基本连续的情况 优点:计算简单、不会产生冲突 缺点:占用连续地址空间,空间效率低 ![[微信截图_20221220140739.png]] + 数字分析法 + 平均取中法 + 折叠法 + 除留余数法:H(key)=key mod p,(p是一个整数),取余 关键:如何选取合适的p? 技巧:设表长度为m,取p<=m且为质数 + 随机数法 #### 如何解决hash冲突 + 开放地址法(开地址法) 基本思想:有冲突时就去寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找到,并将数据元素存入。 例:除留余数法H=(Hash(key)+d1)mod m,d1为增量序列 常用方法: 线性探测法 d1为1,2,3,......m-1线性序列 二次探测法 d1为1平方,-1平方,-2平方......,二次序列 伪随机探测法 d1为伪随机数 + 链地址法(拉链法) 基本思想:相同hash地址的记录链成一个单链表,m个散列地址就设m个单链表,然后用一个数组将m个单链表的表头指针存储起来,形成一个动态的结构 步骤:step1,取数据元素的关键字Key,计算其哈希地址,若该地址对应的链表为空,则插入此链表,否则执行step2解决冲突 step2,计算关键字Key的下一个存储地址,若该地址对应的链表不为空,则利用链表的前插法或后插法将该元素插入此链表 优点:非同义词不会冲突,无聚集现象 链表上节点空间动态申请,适合表长不确定的情况 ![[微信截图_20221220170409.png]] + 再散列法(双散列函数法) + 建立一个公共溢出区 #### 查找效率 ![[微信截图_20221220201301.png]] + 哈希表技术具有很好的平均性能,优于一些传统的技术 + 链地址法由于开地址法 + 除留余数法作为哈希函数优于其他类型的函数