前要知识:hash表有多大就要开多少个空间,记得从0开始。
1.链地址法(又称拉链法、开链法等)Separate chaining hash table
如图所示,今有若干数据,将其使用链地址法存储起来,其示意图如下,如果冲突了就把他接在别人的屁股上,真的是相当方便和简单呢。
2.开放地址法
开放地址法主要有三种方法:
线性探查法(linear probing)、
二次探查法(quadratic probing)、
双重hash(second hash或double hash)
这些都是属于开放地址法
注意对双重hash要与再hash做好区分
首先是线性探查法
这个很简单,就是一次hash后发现要插入的位置已经被别的元素占了,就往下移一个,再冲突再移呗。
默认hash规则都是 mod10.
比如依次插入:
89 18 49 58 9
接下来是平方探查法(二次探查法)
它和线性类似,不过它在遇到冲突时是按照平方来的,并且是正负依次走下去,比如:1,-1,4,-4,9,-9,形如这种。
还是: 89 18 49 58 9
比如49时冲突了(9+1)mod=0;
就插入0号位,58冲突时就正负1不行了都冲突了,就轮到2的平方也就是4
(8+4)mod10=2,所以就放入2号位
,同理其他都是这样。
最后一个是双重hash:
这个很有它的特点,当正常hash时产生了冲突就使用第二个hash函数,形如
hash1(key) = key % TABLE_SIZE
hash2(key) = PRIME – (key % PRIME)
有两个hash的就可以算
第二个hash算出的结果就是待插入元素要从冲突位置往后移的格数,如果往后移了之后还是冲突就继续往后移相同格数,就这样一直移,如果都移过一个循环了,还是没找到可以插入的位置,那就是不能插入了,只能放弃。
比如
要依次插入:
4371 1323 6173 4199 4344 9679 1989
他的hash2函数(冲突时使用的hash函数)是:7-(xmod7)
结果如图所示
当插入6173时发生了冲突,那么它第一次hash时的答案是3,则接下来double hash时就使用hash2函数,则将x=6173带入,得出hash2=1,所以往后移一格,刚好没有冲突,就插入了。
如果是轮到9679则会发现9号位置已经被占,他的hash2=2,则往后移两位,发现1号位也被占了,就往后再移两位,还不行,再移两位,发现5号位是空着的,就插入5号位,
对于1989,hash2=6,无论怎么移都不行,所以就放弃插入。
值得注意的是,移动是可以循环的不是说到9就不能移了,可以接着1继续移。
希望我的注解可以帮到你。