1.哈希表:
哈希表hashtable(key,value) 的做法其实很简单,就是把Key通过一个固定的算法函(哈希函数)转换成一个整型数字,然后就将该数字对数组长度进行取余,取余结果就当作数组的下标,将value(实际的内容,有效的信息)存储在以该数字为下标的数组空间里。
而当使用哈希表进行查询的时候,就是再次使用哈希函数将key转换为对应的数组下标,并定位到该空间获取value,高效快捷。
跟C++容器的Map、Set是一样的。
2.哈希表例题:
百度面试题:
搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来,每个查询串的长度为1-255字节。
假设目前有一千万个记录(这些查询串的重复度比较高,虽然总数是1千万,但如果除去重复后,不超过3百万个。一个查询串的重复度越高,说明查询它的用户越多,也就是越热门。),请你统计最热门的10个查询串,要求使用的内存不能超过1G。
如果采用归并排序(外排序的方式,也可以实现每个数据的排序)这种效率非常低。采用离散状的哈希排序,题目中说明了,虽然有一千万个Query,但是由于重复度比较高,因此事实上只有300万的Query,每个Query255Byte,因此我们可以考虑把他们都放进内存中去,而现在只是需要一个合适的数据结构,在这里,Hash Table绝对是我们优先的选择,因为Hash Table的查询速度非常的快,几乎是O(1)的时间复杂度。
那么,我们的算法就有了:维护一个Key为Query字串,Value为该Query出现次数的HashTable,每次读取一个Query,如果该字串不在Table中,那么加入该字串,并且将Value值设为1;如果该字串在Table中,那么将该字串的计数加一即可。最终我们在O(N)的时间复杂度内完成了对该海量数据的处理。
3.哈希冲突
由于哈希算法被计算的数据是无限的,而计算后的结果范围有限,因此总会存在不同的数据经过计算后得到的值相同,这就是哈希冲突。
解决哈希冲突通常使用:开放定址法、再哈希法、建立公共溢出区等方法。
开放地址法:从发生冲突的那个单元起,按照一定的次序,从哈希表中找到一个空闲的单元。然后把发生冲突的元素存入到该单元的一种方法。
再哈希法:就是同时构造多个不同的哈希函数:Hi = RHi(key) i= 1,2,3 ... k;当H1 = RH1(key) 发生冲突时,再用H2 = RH2(key) 进行计算,直到冲突不再产生,这种方法不易产生聚集,但是增加了计算时间。
建立公共溢出区:分出一个区域,专门放发生溢出情况的数据。
.