hash 表在处理 collision 的时候有很多种方式,比如 线性探测(linear probing)、二次探测(quadratic probing)、开链法(seperate chaning) 等。
本文记录使用开链法的情况下,Hash 表查找成功和查找不成功的平均查找长度(ASL),其他方法同理。
首先开链法是指,每一个表格元素维护一个list,hash function 为我们分配某一个 list,然后在哪个对应的 list 上执行元素的插入、搜寻、删除等操作,虽然针对 list 进行的搜索只能是一种线性操作,但是如果 list 够短,速度还是很快的。
一、查找成功时,平均查找长度
查找成功时的平均查找长度 = 表中每个元素查找成功时的比较次数之和 / 表中元素个数;
使用以下关键字建立哈希表 { 19, 13, 20, 21, 23, 27, 26, 30, 50 },哈希表长度为 10,hash function 为 H(K) = K % 10,并且使用链地址法(就是开链法)解决冲突,则等概率下查找成功的平均查找长度为()?
首先就是按照题意进行 hash 表的构建,构建玩应该如下图:
存放元素 | 50 30 20 | 23 13 | 26 | 27 | 19 | |||||
hash表索引 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
可以看到,查找一个元素,最少需要一次,最多需要三次,那么查找成功时的平均查找长度为:
( 1 * 5 + 2 * 2 + 3 * 1 ) / 9 = 4 / 3
哈希表中的元素个数,就是查找成功时,平均查找长度 4 / 3。
二、查找不成功时,平均查找长度
查找不成功时的平均查找长度 = 表中每个位置查找不成功时的比较次数之和 / 表中位置数(即表长度);
list 长度就是查找不成功时,每个位置的查找长度。
存放元素 | 50 30 20 | 23 13 | 26 | 27 | 19 | |||||
hash表索引 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
还是用上边的例子,这个哈希表的查找不成功时,平均查找长度就是:
( 3 + 0 + 0 + 2 + 0 + 0 + 1 + 1 + 0 + 1 ) / 10 = (3 + 2 + 1 + 1 + 1) / 10 = 8 / 10 = 4 / 5
注意查找成功和不成功联两种情况下,ASL 计算时,分母是不一样的!