关于hash的那点事儿
来源:互联网 发布:太极循环人工智能 编辑:程序博客网 时间:2024/06/05 11:34
hash的由来
为了解决规模很大,查找亦很频繁的问题,模仿数组,通过数组的起始位置和下标就能找到要查找的元素,不需要通过比较,所需的代价就是o(1)。基于借鉴数组查找元素的思想,由此产生了hash。
基本思想
首先在关键字key和记录的存储位置p之间创建一个对应关系H,使得p=H(key),H被称为哈希函数,p被称为散列地址。当创建hash表时,吧关键字为可以的记录放到地址为H(key)的存储空间中,以后查找关键字为key的记录时,在丽影hash函数就可以直接计算出记录的散列地址p,从而达到直接存储的目的。
构造hash函数的方法
除留余数法
用记录的值对小于或者等于边长m的最大素数取余。即H(key)=key%p
假设长度为11,那么H(key)=key%11数字分析法
假设有如下几位数:
49646542 49673242 49687422经过分析可以发现关键字第4到6位分布比较均匀,所以可以取H(key)=d4d5d6平方取中法
通过求关键字的平方值扩大相近数的差别,然后根据表长取其中一部分座位hash的函数值。有一组数0100,0110,1010,将他们每个平方以后得0010000,0012100,1020100,假设表长1000,则可取中间的三位数作为散列地址,即100,121,201分段叠加法
将数分为位数相同的几部分,然后进行叠加。key=926483,H(key)=926+384=1310(折叠叠加方式)或者H(key)=926+483=1419.。要保证位数相同所以去除最高位。H(key)=310或419基数转换法
将关键字看成是某一种进制的数,然后在转换成原来进制的数,在选择其中几位作为散列地址。比如12(13)=2*13^0+1*13^1=15(10),假设表长100,取低两位就好。
hash函数的冲突解决
开放定址法(再散列法)
- 线性探测再散列
如果当前位置有冲突,就看下一个;下一个还有冲突继续看下一个。现有一集合19,01,23,14,55,68,11,82,36
存储过程如下
平均查找长度=(4*1+2*2+3+5+6)/9=22/9 - 二次探测再散列
冲突发生时分别在表的右左进行跳跃式的探测。d=1^2,(-)1^2,2^2,(-2)^2…K^2,(-k)^2
过程如下
平均查找长度=(5*1+2*2+4+3)/9=16/9 - 随机探测再散列
建立随机数发生器,并给定一个随机数作为起始点
链地址法
把所有具有地址冲突的关键字用链表连接起来。现有关键字集合{1,2,3,4,5},表长为3,建立如下表
解决冲突后为
平均查找长度为(3*1+2*2)/5=1.4
- 关于hash的那点事儿
- 关于Contacts的那点事儿
- 关于Contacts的那点事儿(续)
- 关于flex的那点事儿
- 关于viewWillAppear的那点事儿
- 关于QML2的sqlite那点事儿
- 关于Android WebView的那点事儿..
- 关于输入输出的那点事儿
- 关于android传感器的那点事儿
- 关于GitLab中文版的那点事儿
- 关于 SetProcessWorkingSetSize 的那点事儿
- 关于Github的那点事儿
- 关于移动硬盘那点事儿
- 关于PresentModalViewController那点事儿
- 关于JSON那点事儿
- 关于.net那点事儿
- 关于质数那点事儿
- 关于WebView使用的的那点事儿
- 新手司机上路 请多关照
- 参考线
- KEIL declared implicitly 警告问题
- Hdoj2015_偶数求和
- Calendar
- 关于hash的那点事儿
- 继承,重载,包装
- BOOST库 之 智能指针
- [3] UI原型设计工具Pencil Project 学习系列----- 进阶
- Hdoj2016_数据的交换输出
- UVA 10935
- 进程间通信之共享内存
- gitlab安装配置学习
- Hdoj2017_字符串统计