hash冲突随笔

一:hash表
也叫散列表,以key-value的形式存储数据,就是将需要存储的关键码值通过hash函数映射到表中的位置,可加快访问速度。
二:hash冲突
如果两个相同的关键码值通过hash函数映射到了表中的相同位置,则产生了“碰撞”及hash冲突。解决冲突的方式有多种,可根据实际情况选择。
三:解决方法
1.外部链址法
为hash冲突的关键码值建立单链表,将单链表的头指针保存在hash表的存储单元中。以HashMap为例,可以实例化一个初始容量为16和加载因子为0.75f的对象。首先会创建一个长度为16 的哈希表,相当于定义了一个由16个头指针(初始为空)组成的指针数组T[0...m-1],凡是hash结果为i的节点均插入到以T[i]为头指针的单链表中。数据越多,碰撞发生就越多,当哈希表的容量达到某个临界点时(数组长度*加载因子)就会对表进行扩容。扩容非常耗时,需要计算数据在新表中的位置并进行复制。所以如果事先知道HashMap中需要存储的数量,最好预设HashMap的初始容量能大大提升系统系能。
查找时间:链表查找时间+1;
2.再哈希法
也称作再散列法,当发生碰撞后使用不同的hash函数再次进行hash操作,直到不再冲突。
数据比较分散,但是增加了计算时间,不太可能进行删除操作。
3.建立公共溢出区
创建两个哈希表,一个为基本表,一个为公共表,如果需要存储的数据hash后和基本表中有冲突,则保存在公共表中,公共表为顺序表,可将冲突的数据一次插入到公共顺序表中。
查询数据的时候先根据hash值去基本表中查找,如果和数据不匹配再去公共表中顺序查找即可。
4.开放定址发
称作再散列法,当冲突发生后以同样的hssh函数再次进行不同规则的操作,直到不冲突为止。
表达式:Hi = (H(key) + di)%m i=1,2,3,...,n。根据di的的不同可分为:
1)线性探测再散列:di为线性函数即可,通常di = 1,2,3,...,m-1
冲突发生后顺序查找表中的下一个单元,直到找到空单元
2)二次探测再散列:di = 1^2,-1^2,2^2,-2^2,...,k^2,-k^2 (k<m/2)
冲突发生后,在表的左右两侧进行探测。
3)伪随机探测再散列:di = 随机数
冲突发生后,在表的位置随机进行探测。
查询操作则根据相同的存储规则进行查询操作即可。
特点:不太可能进行删除操作,当表快满状态时,效率下降。
posted @ 2017-03-23 10:58  魔术员  阅读(133)  评论(0编辑  收藏  举报