[数据结构] 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建立公共溢出区

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

相关文章
|
4月前
|
存储 算法 NoSQL
海量数据处理数据结构之Hash与布隆过滤器
随着网络和大数据时代的到来,我们如何从海量的数据中找到我们需要的数据就成为计算机技术中不可获取的一门技术,特别是近年来抖音,快手等热门短视频的兴起,我们如何设计算法来从大量的视频中获取当前最热门的视频信息呢,这就是我们今天即将谈到的Hash和布隆过滤器。以下是Hash和布隆过滤器的一些常见应用:
42 2
|
4月前
|
存储 NoSQL Serverless
Redis数据结构之——hash
Redis数据结构之——hash
|
5月前
|
算法 JavaScript 前端开发
JavaScript算法和数据结构:写一个二分查找的函数。
JavaScript算法和数据结构:写一个二分查找的函数。
33 0
|
8天前
【数据结构】二叉树-堆(函数实现)
【数据结构】二叉树-堆(函数实现)
13 2
|
16天前
|
Cloud Native 关系型数据库 MySQL
云原生数据仓库产品使用合集之在ADB中,如何将源数据的多表(数据结构一致)汇总到一张表
阿里云AnalyticDB提供了全面的数据导入、查询分析、数据管理、运维监控等功能,并通过扩展功能支持与AI平台集成、跨地域复制与联邦查询等高级应用场景,为企业构建实时、高效、可扩展的数据仓库解决方案。以下是对AnalyticDB产品使用合集的概述,包括数据导入、查询分析、数据管理、运维监控、扩展功能等方面。
|
19天前
|
存储 NoSQL 算法
Redis入门到通关之Redis数据结构-Hash篇
Redis入门到通关之Redis数据结构-Hash篇
23 1
|
28天前
|
Python
python学习-函数模块,数据结构,字符串和列表(下)
python学习-函数模块,数据结构,字符串和列表
72 0
|
28天前
|
索引 Python
python学习-函数模块,数据结构,字符串和列表(上)
python学习-函数模块,数据结构,字符串和列表
30 0
|
2月前
|
Java 数据库连接 API
Java 学习路线:基础知识、数据类型、条件语句、函数、循环、异常处理、数据结构、面向对象编程、包、文件和 API
Java 是一种广泛使用的、面向对象的编程语言,始于1995年,以其跨平台性、安全性和可靠性著称,应用于从移动设备到数据中心的各种场景。基础概念包括变量(如局部、实例和静态变量)、数据类型(原始和非原始)、条件语句(if、else、switch等)、函数、循环、异常处理、数据结构(如数组、链表)和面向对象编程(类、接口、继承等)。深入学习还包括包、内存管理、集合框架、序列化、网络套接字、泛型、流、JVM、垃圾回收和线程。构建工具如Gradle、Maven和Ant简化了开发流程,Web框架如Spring和Spring Boot支持Web应用开发。ORM工具如JPA、Hibernate处理对象与数
95 3
|
3月前
|
存储 算法
《剑指offer》之“包含min函数的栈”题解
《剑指offer》之“包含min函数的栈”题解
11 0