数据结构(十二)散列表

定义

以下简称hahs

应用场景

适合查找与给定值相同的数据,不适合做范围查找,1对多映射查找

问题

冲突,散列表的理论依据是每个不同的关键字通过散列算法得到的结果都是唯一的,而现实中有可能出现几个结果相同的关键字。

hash算法

构造一个散列算法考虑几个方面

直接定址法

按如下公式计算出关键字的hash值,当原始的key不重复,则得到的hash值就不会冲突

数字分析法

抽取关键字的一部分作为hash值

例如手机号,一般可以取后4位或者后4位的变形作为hash值,(公司内部场景)

平方取中法

折叠法

除留余数法

随机数法

java针对stirng的hash算法

hash = 31 * hash + str[i];

其中str[i]表示string的某个位置字符

至于为什么用31那。首先你必须使用一个质数,那又会问,为什么要用质数呢,如果你使用一个有因数的数,那么相乘得到的结果会出现更多的hash冲突。那为什么选择31呢,i*31== (i<<5)-1,可以被编译器优化为移位计算,那为什么不选7呢,i*7==(i<<3)-1,系数尽可能大也可以减少hash冲突,但是太大相乘可能会导致溢出,所以31是一个折中的系数。详细可以参考这个解释

https://stackoverflow.com/questions/299304/why-does-javas-hashcode-in-string-use-31-as-a-multiplier

hash冲突解决方法

开放地址法

线性探测法

公式

比如

二次探测法

可以不让关键字都聚集在同一块数据区域汇中(增加离散度)

随机探测法

需要注意的是,这个随机数是一个伪随机数,否则下次找不到hash值了

再hash法

当遇到冲突时,对关键字再进行hash,可以采用不同的hash函数计算,目的是为了得到一个不冲突的hash值

链表法

原理是不处理hash冲突的问题,就是让它冲突,然后把冲突的关键字用链表串联起来,下次找的时候直接遍历链表就行了。多说一句,java的hashmap就是采用这个方法

拿图来说就比如这样

公共溢出区

链表发是在每个位置上建立冲突的集合,而公共溢出区则为建立一个统一的冲突集合,这应该挺好理解。这适用用hash冲突较少的场景,如果多了,会影响性能,要知道遍历链表的复杂度是O(n),还不如直接二分查找了。

时间: 2024-10-12 16:42:17

数据结构(十二)散列表的相关文章

数据结构复习之散列表查找(哈希表)

一.散列表相关概念 散列技术是在记录的存储位置和它的关键字之间建立一个确定的对应关系f,使得每个关键字key对应一个存储位置f(key).公式如下: 存储位置 = f(关键字) 这里把这种对应关系f称为散列函数,又称为哈希(Hash)函数.按这个思想,采用散列技术将记录存在在一块连续的存储空间中,这块连续存储空间称为散列表或哈希表.那么,关键字对应的记录存储位置称为散列地址. 散列技术既是一种存储方法也是一种查找方法.散列技术的记录之间不存在什么逻辑关系,它只与关键字有关,因此,散列主要是面向查

数据结构和算法: 散列表

散列表(Hash table,也叫哈希表),是根据键(Key)而直接访问在内存存储位置的数据结构.也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度.这个映射函数称做散列函数,存放记录的数组称做散列表 散列表的时间复杂度不是严格的O(1), 因为和多种因素有关, 比如散列函数, 还有就是如果采用链表法处理冲突, 那么最坏情况是所有数据都散列到一个链表中, 此时是O(n). hash函数有以下几种简单实现的方法 取余法 常见的对一个数进行取余操作

数据结构与算法——散列表类的C++实现(分离链接散列表)

散列表简介: 散列表的实现常被称为散列.散列是一种用于以常数平均时间执行插入.删除和查找的技术. 散列的基本思想: 理想的散列表数据结构只不过是一个包含一些项的具有固定大小的数组.(表的大小一般为素数) 设该数组的大小为TbaleSize,我们向该散列表中插入数据,首先我们将该数据用一个函数(散列函数)映射一个数值x(位于0到TbaleSize1-1之间):然后将该数据插入到散列表的第x的单元.(如果有多个数据映射到同一个数值,这个时候就会发生冲突) 散列函数介绍: 为了避免散列函数生成的值不是

浅谈算法和数据结构: 十二 无向图相关算法基础

从这篇文章开始介绍图相关的算法,这也是Algorithms在线课程第二部分的第一次课程笔记. 图的应用很广泛,也有很多非常有用的算法,当然也有很多待解决的问题,根据性质,图可以分为无向图和有向图.本文先介绍无向图,后文再介绍有向图. 之所以要研究图,是因为图在生活中应用比较广泛: 无向图 图是若干个顶点(Vertices)和边(Edges)相互连接组成的.边仅由两个顶点连接,并且没有方向的图称为无向图. 在研究图之前,有一些定义需要明确,下图中表示了图的一些基本属性的含义,这里就不多说明. 图的

python数据结构(二)------列表

本文将重点梳理列表及列表操作. 2.1 list函数 2.2 基本列表操作 2.3 列表方法 2.1 list函数 >>>list('hello') ['h','e','l',l','o'] 注:list函数适用于所有类型的序列,而不只是字符串. 2.2 基本列表操作 2.2.1 改变列表:元素赋值 >>>x = [1,3,5] >>>x[0] = 'a' >>>x ['a',3,5] 注:不能对不存在的元素赋值,即x[0]~x[2]

散列表(一).散列表基本内容介绍

一说到散列表,大家脑子想到的词就是:Hashmap.key-value.查找速度快.增删速度快等等.确实,在我们平常的学习生活中,散列表是很常见.也是用的很多的数据结构.那么散列表是怎样设计出来的,为什么它既可以和数组一样查询快,又可以和链表一样快增删,本节让我们一起了解一下什么是散列表.什么是散列函数.它究竟是如何设计出来的. 散列思想 什么是散列思想呢?散列表还有一个英文名叫做Hashtable,也叫做"哈希表"."hash表",hash我们都了解,是同过一定的

9-12-哈希查找表/散列表-查找-第9章-《数据结构》课本源码-严蔚敏吴伟民版

课本源码部分 第9章  查找 - 哈希查找表/散列表 ——<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接??? <数据结构-C语言版>(严蔚敏,吴伟民版)课本源码+习题集解析使用说明        课本源码合辑  链接??? <数据结构>课本源码合辑        习题集全解析  链接??? <数据结构题集>习题解析合辑        本源码引入的文件  链接? Base.c        相关测试数据下载  链接? 数据包      

深入浅出数据结构C语言版(14)——散列表

我们知道,由于二叉树的特性(完美情况下每次比较可以排除一半数据),对其进行查找算是比较快的了,时间复杂度为O(logN).但是,是否存在支持时间复杂度为常数级别的查找的数据结构呢?答案是存在,那就是散列表(hash table,又叫哈希表).散列表可以支持O(1)的插入,理想情况下可以支持O(1)的查找与删除. 散列表的基本思想很简单: 1.设计一个散列函数,其输入为数据的关键字,输出为散列值n(正整数),不同数据关键字必得出不同散列值n(即要求散列函数符合单射条件) 2.创建一个数组HashT

数据结构--散列排序--散列表

散列表 散列查找,我们又回到了查找, 编译的时候,涉及变量及属性的管理: 插入:新变量的定义 查找:变量的引用 实际上是动态查找问题,查找树AVL树. 两个变量名(字符串)比较效率不高.字符串的比较要一个一个的比下去,时间会比较长, 是否可以把字符串转换成数字,再处理,就快多了.就是散列查找的思想. 已知的查找方法: 顺序查找                                          O(N) 二分查找(静态查找,不适合动态查找)   O(log2N) 二叉搜索数