[数据结构] Hash表、Hash函数及冲突解决

简介:

1.Hash表

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

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

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

2.哈希表的构造方法

2.1直接定址法

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

2.2 数字分析法

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

2.3 平方取中法 

  以关键字的平方值的中间几位作为存储地址(哈希地址)。求“关键字的平方值” 的目的是“扩大差别” ,同时平方值的中间各位又能受到整个关键字中各位的影响。 

  此法适于:关键字中的每一位都有某些数字重复出现频度很高的现象。

2.4 折叠法 

   将关键字分割成若干部分,然后取它们的叠加和为哈希地址。两种叠加处理的方法:移位叠加:将分 割后的几部分低位对齐相加;间界叠加:从一端沿分割界来回折叠,然后对齐相加。 
 
此法适于:关键字的数字位数特别多。 

2.5随机数法

  设定哈希函数为:H(key) = Random(key)其中,Random 为伪随机函数 
此法适于:对长度不等的关键字构造哈希函数。

2.6除留余数法

  取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址.即 
哈希函数为:H(key) = key MOD p ( p≤m ),其中, m为表长,p 为不大于 m 的素数。

3.哈希表冲突解决方法

  哈希表处理冲突主要有开放寻址法再散列法链地址法(拉链法)和建立一个公共溢出区四种方法。 
通过构造性能良好的哈希函数,可以减少冲突,但一般不可能完全避免冲突,因此解决冲突是哈希法的另一个关键问题。 
“处理冲突” 的实际含义是:为产生冲突的关键字寻找下一个哈希地址。

3.1开放定址法

   
一旦发生了冲突,就去寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找到,并将记录存入。

3.1.1线性探测

  冲突发生时,顺序查看表中下一单元,直到找出一个空单元或查遍全表。

  公式: 

fi(key) = (f(key)+di) MOD m (di=1,2,3,......,m-1)

3.1.2二次探测法

  冲突发生时,在表的左右进行跳跃式探测,双向寻找到可能的空位置。

公式:

fi(key) = (f(key)+di) MOD m (di = 12, -12, 22, -22,……, q2, -q2, q <= m/2

3.1.3随机探测法

  在冲突时,对于位移量 di 采用随机函数计算得到,我们称之为随机探测法。

 公式: 

fi(key) = (f(key)+di) MOD m (di是一个随机数列)

  线性探测再散列容易产生“二次聚集”,即在处理同义词的冲突时又导致非同义词的冲突。 
线性探测再散列的优点是:只要哈希表不满,就一定能找到一个不冲突的哈希地址,而二次探测再散列和伪随机探测再散列则不一定。

3.2链地址法

   将所有哈希地址相同的记录都链接在同一链表中。各链表上的结点空间是动态申请的,故它更适合于造表前无法确定表长的情况。 
处理冲突简单,且无堆积现象,即非同义词决不会发生冲突,因此平均查找长度较短;

3.3再哈希法

这种方法是同时构造多个不同的哈希函数:

Hi=RH1(key),i=1,2,3,…,n.

当哈希地址Hi=RH1(key)发生冲突时,再计算Hi=RH2(key)……,直到冲突不再产生。这种方法不易产生聚集,但增加了计算时间。

3.4建立公共溢出区

  这种方法的基本思想是:将哈希表分为基本表和溢出表两部分,凡是和基本表发生冲突的元素,一律填入溢出表.(注意:在这个方法里面是把元素分开两个表来存储)

相关文章
|
1月前
|
算法
数据结构和算法学习记录——线性表之双向链表(上)-结点类型定义、初始化函数、创建新结点函数、尾插函数、打印函数、尾删函数
数据结构和算法学习记录——线性表之双向链表(上)-结点类型定义、初始化函数、创建新结点函数、尾插函数、打印函数、尾删函数
23 0
|
12天前
|
存储 JavaScript 前端开发
JavaScript中的对象是数据结构,存储键值对,键为字符串,值可为任意类型,包括函数(作为方法)
【6月更文挑战第25天】JavaScript中的对象是数据结构,存储键值对,键为字符串,值可为任意类型,包括函数(作为方法)。
14 2
|
1月前
数据结构学习记录——判断是否为同一颗二叉搜索树(题意理解、求解思路、程序搭建框架、具体函数的实现)
数据结构学习记录——判断是否为同一颗二叉搜索树(题意理解、求解思路、程序搭建框架、具体函数的实现)
17 2
|
1月前
|
算法 搜索推荐
数据结构和算法——表排序(算法概述、物理排序、复杂度分析,包含详细清晰图示过程)
数据结构和算法——表排序(算法概述、物理排序、复杂度分析,包含详细清晰图示过程)
13 0
|
1月前
|
数据库
电商购物系统商品数据结构设置 -- 商品类别表
电商购物系统商品数据结构设置 -- 商品类别表
|
1月前
|
存储 算法
数据结构学习记录——集合及运算(集合的表示、并查集、树结构表示集合、集合运算、查找函数、并运算)
数据结构学习记录——集合及运算(集合的表示、并查集、树结构表示集合、集合运算、查找函数、并运算)
8 0
|
1月前
|
算法
数据结构和算法学习记录——初识二叉树(定义、五种基本形态、几种特殊的二叉树、二叉树的重要性质、初识基本操作函数)
数据结构和算法学习记录——初识二叉树(定义、五种基本形态、几种特殊的二叉树、二叉树的重要性质、初识基本操作函数)
11 0
|
1月前
|
存储 算法
数据结构和算法学习记录——特殊线性表之队列-队列的概念、队列结构体类型定义 、基本接口函数、初始化函数、销毁队列函数、入队列函数、判断队列是否为空、出队列函数、读取队头队尾的数据 、计算队列数据个数
数据结构和算法学习记录——特殊线性表之队列-队列的概念、队列结构体类型定义 、基本接口函数、初始化函数、销毁队列函数、入队列函数、判断队列是否为空、出队列函数、读取队头队尾的数据 、计算队列数据个数
16 0
|
1月前
|
算法 C语言
数据结构和算法学习记录——特殊线性表之栈(下)-销毁栈函数、判断栈是否为空、压栈函数、出栈函数、取栈顶元素、计算栈中有多少个元素、栈有关习题-有效的括号
数据结构和算法学习记录——特殊线性表之栈(下)-销毁栈函数、判断栈是否为空、压栈函数、出栈函数、取栈顶元素、计算栈中有多少个元素、栈有关习题-有效的括号
14 0
|
1月前
|
算法
数据结构和算法学习记录——特殊线性表之栈(上)-栈的概念、栈的结构、链式栈数组栈、栈的结构体定义、栈的基本接口函数、栈顶初始化函数
数据结构和算法学习记录——特殊线性表之栈(上)-栈的概念、栈的结构、链式栈数组栈、栈的结构体定义、栈的基本接口函数、栈顶初始化函数
12 0