声明:本篇博客根据回顾老师上课知识和书籍《数据结构——用C语言描述》(耿国华)整理得出,仅作知识回顾学习用。

1.哈希法

哈希法又称散列法、杂凑法、关键字地址计算法。相对应的表称为哈希表、散列表、或杂凑表等。

哈希方法思想
首先在元素的关键字k和元素的存储位置p之间建立一个对应关系H,使得 p = H(k),H成为哈希函数。创建哈希表时,把关键字为k的元素直接存入地址为H(k)的单元,以后查找关键字为k的元素时,再利用哈希函数计算该元素的存储位置。再按关键字存取元素。Hash中存储的key值都是唯一的。
哈希冲突:
当关键字集合很大的时候,关键字值不同的元素可能会映射到哈希表的同一个地址,即k1 != k2,H(k1) == H(k2),这种现象称为冲突,此时k1和k2为同义词。事实上冲突是不可避免的,由于关键字可能发生冲突的集合远远大于实际开辟的哈希表长度 ,构成冲突的必然性,可通过改进哈希的性能来减少冲突,即降低冲突的可能性。

2.哈希函数的构造方法

构造哈希函数原则
(1)函数本身便于计算
(2)计算出来的地址分布均匀,即对应任意一个关键字k,H(k)对应的不同地址的概率应该相同,以尽可能减少冲突

在实际应用中,构造哈希函数要考虑以下五个因素:
(1)计算哈希函数所需要的时间。哈希函数一定要简单,取放key值都需要根据哈希函数和key值计算位置,计算是要花时间的,尽可能要计算简单一点,这样计算时间也会少。
(2)关键字的长度。关键字过长,我们可以考虑取关键的某几位来建立哈希函数。
(3)哈希表的大小。哈希表可以减少查找次数,但是哈希表过短,或者过长都会使哈希法性能降低。
(4)关键字分布情况。为了使key值和哈希函数计算出来的地址分布均匀,要考虑关键字分布情况建立合适哈希函数。
(5)记录查找的频率。

2.1数字分析法

方法
首先大概了解关键字集合。如果每个关键字的位数比哈希表的地址码位数多时,可以从key值选择分布均匀的若干位,构成哈希地址。
比如哈希表长度为100,即地址空间为0~99,如果有200个key值,且key值都是8位十进制数d1d2d3d4d5d6d7d8,那么我们可以选择分布较均匀的两位数字作为key值。比如说所有key中,第二位和第五位数字都分布较均匀(即200个key值的第二位第五位都比较随机),那么我们就取d2d5作为key值地址码,比如 34982748,地址码为42。
(在这里存在不相同的key值,但是地址码一样,这是哈希冲突,哈希冲突解决办法在最后给出。哈希表,一个地址码可以代表(存放)一组数据)。

2.2平方取中法

方法
当无法确定关键字中哪几位分布较均匀时,可以求出关键字的平方值,再结合哈希表长度,取平方值的中间几位作为哈希地址(比如哈希表长度是 100,那哈希地址就00-99,我们就取key值平方后的中间2位作为地址码;如果哈希表长度是1000,那么哈希地址可以是000-999,那么就取key值平方后的中间3位作为地址码)。这是因为完成平方运算后,中间几位和关键字的每一位都相关,所以不同关键字会以较高的概率产生不同的哈希地址。

2.3分段叠加法

按哈希表地址位数将关键字分成位数相等的几部分(最后一部分可以较短),然后将这些部分相加,舍弃最高进位,剩下的数字作为地址码。比如哈希表长度为1000,可以表示地址码000-999。我们就把key值分成三位数为一部分。具体折叠方法有移位法和折叠法。以为叠加法直接将每一部分相加。折叠叠加法是将奇数段和偶数段分开,奇数段(偶数段)正常,偶数段(奇数段)倒序,再相加。

举例:12360324711202065

2.4除留余数法

顾名思义,即对key值进行取余。看有多少key值,如果有几十个key值,我们可以选择对10取余,对15取余,等等。余数就是对应的地址码。

其实不论什么方法,目的都是为了在保证哈希函数尽可能简单的情况下让key值计算出来的地址码尽可能均匀。即让哈希表起到提高查找效率的作用。所以不管什么方法,只要达到最终这个目的就行。

2.5伪随机数法

即用一个为随机函数作为哈希函数p = H(key) = random(key)。

3.处理冲突的方法

3.1开放定址法

也叫做再散列法
思想:当关键字key的初始哈希地址p0 = H(key)出现冲突时(即该地址有key值了),以p0为基础,产生另一个地址p1,如果p1仍然冲突,再以p0为基础,产生另一个哈希地址p2…直至找到一个不冲突的地址pi,将key值存到里面。
即hi = (h0 + di)%m
m为表长,m为增量序列
(1)线性探测再散列
di = 1,2,3,4,…,m-1
(2)二次探测再散列
di = 1^2, -1^2, 2^2, -2^2,…, k^2, -k^2(k <= m/2)

3.2再哈希法

同时构造多个不同的哈希函数:
Hi = RHi(key)
哈希地址H1 = RH1(key)差生冲突时,再计算H2 = RH2(key)…直到冲突不再产生。

3.3建立公共溢出区

哈希表分为基本表溢出表两部分,凡是和基本表发生冲突的元素一律填入溢出表。

3.4链地址法

哈希表里每个表格是一个地址码和一个指针。将对应的key值都放在(key,指针)这种空间中,连接在对应的地址码后面。比如我们哈希表的地址码是key值对10取余。
有数10,12 ,32,34,92,33,11,67,那么都映射到哈希表上,对应的结构为

结构体类型如下:

#define TABLESIZE 10
typedef int KeyType; // 键值的类型
typedef struct
{KeyType key; // 学生信息 学号//....其他数据成员 姓名//....其他数据成员
}DataType; // 存储的数据类型typedef struct
{DataType key;KeyNode* next;
}KeyNode;//key以这种结点方式被连接typedef struct Node
{int addcode;//地址码(0,1,2,3,...,9)KeyNode* next;//指向KeyNode类型的结点
}List;//哈希表每个格子的结构typedef struct Hash
{List* hash_table[TABLESIZE];
}ListHash;//哈希表

Hash——哈希法概念、哈希函数构造方法、哈希冲突解决办法(重点讨论链地址法)相关推荐

  1. 除留余数法构造哈希函数并用链地址法处理哈希冲突【C++实现】

    1.题目描述 哈希函数为H(key)=key%13,哈希冲突处理方法为:链地址法 c语言版数据结构上的例子 2.代码实现 首先建立一个哈希链表结点类HashNode,用于存放处理冲突时的关键字,其数据 ...

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

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

  3. Hash(哈希)相关知识(哈希函数、哈希查找)

    Hash(哈希)相关知识 前言 一. 哈希函数 1. 函数特性 1.1 基本的哈希函数 1.2 加密的哈希函数 2. 常见的哈希函数构造法 2.1 直接寻址法 2.2 数字分析法 2.3 平方取中法 ...

  4. 哈希表的基本概念详解以及具体实现(哈希函数、哈希冲突、负载因子)

    一.哈希表 哈希表是一个典型的用空间换时间的操作,利用数组随机访问的特性,最大化查找效率.哈希过程就是将数组元素与下标建立关系的过程. 二.哈希函数 1.哈希函数的意义: 哈希表是希望将元素与下标建立 ...

  5. 基础提升*哈希函数与哈希表

    目录 1:哈希函数与哈希表 2:利用哈希表建立新的结构: 3:布隆过滤器(黑名单的查询与建立) 4:一致性哈希 情景假设: 原始问题: 解决方法(一致性哈希) 一致性哈希的优点: 存在的问题: 解决方 ...

  6. 高级数据结构与算法 | 哈希 :哈希冲突、负载因子、哈希函数、哈希表、哈希桶

    文章目录 哈希 哈希函数 常见的哈希函数 字符串哈希函数 哈希冲突 闭散列的解决方法 开散列的解决方法 负载因子以及增容 对于闭散列 对于开散列结构 具体实现 哈希表(闭散列) 插入 查找 删除 完整 ...

  7. java取余数的函数_左神算法基础:哈希函数和哈希表

    笔者在读研刚开始的时候,偶尔看面经,有这样一个问题:只用2GB内存在20亿个整数中找到出现次数最多的数,当时的我一脸懵逼,怎么去思考,20亿个数?What The Fuck! 但是,看完今天的文章,你 ...

  8. igs无法分配驱动器映射表_左神算法基础:哈希函数和哈希表

    笔者在读研刚开始的时候,偶尔看面经,有这样一个问题:只用2GB内存在20亿个整数中找到出现次数最多的数,当时的我一脸懵逼,怎么去思考,20亿个数?What The Fuck! 但是,看完今天的文章,你 ...

  9. 使用哈希函数:H(k)=3k MOD 11,并采用链地址法处理冲突。试对关键字序列(22,41,53,46,30,13,01,67)构造哈希表,求等概率情况下查找成功的查找长度,并设计构造哈希表

    使用哈希函数:H(k)=3k MOD 11 ,并采用链地址法处理冲突. 试对关键字序列(22,41,53,46,30,13,01,67)构造哈希表, 求等概率情况下查找成功的查找长度,并设计构造哈希表 ...

最新文章

  1. 怎么使用 Caffe 进行 LetNet-5 的训练和预测
  2. 防火墙安装的十步骤,加强网络第一道保护屏
  3. 转:ext2文件系统详解
  4. v8学习笔记(五) 编译过程
  5. ExtJs2.0学习系列(8)--Ext.FormPanel之第五式(综合篇)
  6. 区块链学习笔记:DAY01 区块链的技术原理
  7. java命令行执行编译好的类_Java命令行编译并执行Java程序
  8. Revit API多选多重过滤
  9. python通过ntohl和htonl等函数实现主机字节序和网络字节序相互转换
  10. HTML5定位功能,实现在百度地图上定位
  11. Retinex实验效果图和图片格式转化的失真问题
  12. bundle adjustment原理(1)
  13. svn服务端可视化界面
  14. 华东师大计算机全国排名,华东师范大学就这水平进的985?
  15. MATLAB中plot函数的用法
  16. thinkphp 批量打包下载图片到本地电脑
  17. TVP5147调试经验
  18. 知识点四 图论:dijkstra (HDU 2544 +HDU 1874)
  19. 第 1 章 程序设计基本方法
  20. http://windowsandroid.cn.uptodown.com/download

热门文章

  1. 乐视x820android最新版本,乐视MAX2|MIUI10|安卓8.1|最终完美版极速流_最新最全的乐Max2ROM刷机包下载、刷机教程...
  2. 【共识专栏】共识的分类(上)
  3. 如何将excel表格导入matlab,将Excel数据导入MATLAB中的方法
  4. 经典利用永恒之蓝漏洞对Windows操作系统进行攻击
  5. 【计算机网路-第四章】IP地址和子网掩码
  6. 阎王爷让我给他做个后台管理系统(转)
  7. c语言 程序段 数据段,C语言程序的段
  8. Work20230407
  9. 京东有多少钱可以重来?
  10. 长坡难滚“雪球”,零跑汽车上市只是一个 “开端”