下面线性探测法和链地址法我各举一个例子。
线性探测法求ASL
将关键字序列(7、8、30、11、18、9、14)散列存储到散列表中,散列函数为H(Key) = (key x 3) MOD 7,处理冲突采用线性探测再散列法,要求装填因子为0.7
装填因子 a = 表中装入的记录个数散列表的长度\frac{表中装入的记录个数}{散列表的长度}散列表的长度表中装入的记录个数 = 0.7,可以求出散列表表长 = 7 0.7 \frac{7}{0.7}0.77 = 10
(7x3)mod 7 = 0,因此散列地址为 0
(8x3)mod 7 = 3,因此散列地址为 3
(30x3)mod 7 = 6,因此散列地址为 6
(11x3)mod 7 = 5,因此散列地址为 5
(18x3)mod 7 = 5,此时和11冲突,使用线性探测法(地址+1),又和30冲突,地址再次+1,无冲突,散列地址为 7
(9x3)mod 7 = 6,此时和30冲突,使用线性探测法(地址+1),又和18冲突,地址再次+1,无冲突,散列地址为 8
(14x3)mod 7 = 0,此时和7冲突,使用线性探测法(地址+1),无冲突,散列地址为 1
线性探测法处理冲突构造所得的哈希表如下:

地址0123456789
key71481130189

根据公式:查找成功时ASL = 1 n \frac{1}{n}n1 ∑ i = 1 n C i \sum_{i=1}^{n} C_i∑i=1nCi
如果查找7,则需要查找1次。
如果查找8,则需要查找1次。
如果查找30,则需要查找1次。
如果查找11,则需要查找1次。
如果查找18,则需要查找3次:第一次查找地址5,第二次查找地址6,第三次查找地址7,查找成功。
如果查找9,则需要查找3次:第一次查找地址6,第二次查找地址7,第三次查找地址8,查找成功。
如果查找14,则需要查找2次:第一次查找地址0,第二次查找地址1,查找成功。
所以,查找成功时ASL=(1+2+1+1+1+3+3)/ 7 = 12/ 7
根据公式:查找不成功时ASL = 1 r \frac{1}{r}r1 ∑ i = 1 n C i \sum_{i=1}^{n} C_i∑i=1nCi
举个例子来说吧:
如果要查找key为9的关键字。根据散列函数可以计算H(key)=H(9)=6。
此时在会检测地址为6的值,发现key=30,不等于9。这就说明在装填的时候发生了冲突。
根据冲突处理方法,会继续检测地址为0的值,之所以没有检测地址7,8,9,H(key)的取值取不到这些值。检测地址为0的值,发现key=7,依然不等。
根据冲突处理方法,会继续检测地址为1的值,发现key=14,依然不等。
根据冲突处理方法,会继续检测地址为2的值,发现key为空。
这就说明关键字9从应该出现的地址6,一直查找,找到值为空的地址都没有和9相等的,说明散列表中没有9这个值,因此探测次数为4次
根据上面的例子
查找地址为0的值所需要的次数为3,
查找地址为1的值所需要的次数为2,
查找地址为2的值所需要的次数为1,
查找地址为3的值所需要的次数为2,
查找地址为4的值所需要的次数为1,
查找地址为5的值所需要的次数为5,
查找地址为6的值所需要的次数为4。
所以,查找不成功ASL=(3+2+1+2+1+5+4)/ 7 = 18/ 7
链地址法求ASL
将关键字序列{1 13 12 34 38 33 27 22} 散列存储到散列表中。散列函数为:H(key)=key mod 11,处理冲突采用链地址法,求在等概率下查找成功和查找不成功的平均查找长度
1mod11=1,因此散列地址为1
13mod11=2,因此散列地址为2
12mod11=1,因此散列地址为1(这个数据是数据1指针的另一个新数据)
34mod11=1,因此散列地址为1(这个数据是数据12指针的另一个新数据)
38mod11=5,因此散列地址为5
33mod11=0,因此散列地址为0
27mod11=5,因此散列地址为5(这个数据是数据38指针的另一个新数据)
22mod11=0,因此散列地址为0(这个数据是数据33指针的另一个新数据)
链地址法处理冲突构造所得的哈希表如下:
根据公式:查找成功时ASL = 1 n \frac{1}{n}n1 ∑ i = 1 n C i \sum_{i=1}^{n} C_i∑i=1nCi
如果查找1,则需要查找3次。从地址1开始查,第一次查到34,第二次查到12,第三次查到1。
如果查找13,则需要查找1次。
如果查找12,则需要查找2次。从地址1开始查,第一次查到34,第二次查到12。
如果查找34,则需要查找1次。
如果查找38,则需要查找2次。从地址5开始查,第一次查到27,第二次查到38。
如果查找33,则需要查找2次。从地址0开始查,第一次查到22,第二次查到33。
如果查找27,则需要查找1次。
如果查找22,则需要查找1次。
所以,查找成功ASL =(3×1+2×3+1×4)/8 = 13/8
根据公式:查找不成功时ASL = 1 r \frac{1}{r}r1 ∑ i = 1 n C i \sum_{i=1}^{n} C_i∑i=1nCi
举个例子来说吧:
如果要查找key为16的关键字。根据散列函数可以计算H(key)=H(16)=5。
首先从地址5开始查找,第一次查找到的数据是27,和16不相等,继续往后找。
第二次查找到的数据是38,和16不相等,继续往后找。
第三次查找到的数据是空,查找结束。意味着在地址5这一行找不到关键字16,因为如果关键字16在表中存在的话,只可能在地址5这一行,现在在地址5这一行找不到,意味着整个表也找不到。
如果要查找key为20的关键字。根据散列函数可以计算H(key)=H(20)=9。
首先从地址9开始查找,第一次查找到的数据是空,查找结束。意味着表中不存在关键字20。
根据上面的例子
查找地址为0的值所需要的次数为3,
查找地址为1的值所需要的次数为4,
查找地址为2的值所需要的次数为2,
查找地址为3的值所需要的次数为1,
查找地址为4的值所需要的次数为1,
查找地址为5的值所需要的次数为3,
查找地址为6的值所需要的次数为1,
查找地址为7的值所需要的次数为1,
查找地址为8的值所需要的次数为1,
查找地址为9的值所需要的次数为1,
查找地址为10的值所需要的次数为1。
所以,查找不成功ASL = (3+4+2+1+1+3+1+1+1+1+1)/11 = 19/11
其实不管是线性探测法还是链地址法,在求查找不成功ASL时,都是差不多的。首先根据散列函数找到地址,然后从这个地址往后查,一直查到空结束。
它通过把关键码值映射到哈希表中的一个位置来访问记录,以加快查找的速度。这个映射函数就做散列函数,存放记录的数组叫做散列表。 2、散列存储的基本思路 以数据中每个元素的关键字K为自变量,通过散列函数H(k)...
一、哈希表
1、概念
哈希表(Hash Table)也叫散列表,是根据关键码值(Key Value)而直接进行访问的数据结构。它通过把关键码值映射到哈希表中的一个位置来访问记录,以加快查找的速度。这个映射函数就做散列函数,存放记录的数组叫做散列表。