哈希表:线性探测法和链地址法求查找成功与不成功的平均查找长度

    技术2022-07-10  151

    哈希表:线性探测法和链地址法求查找成功与不成功的平均查找长度

    了解ASL的公式线性探测法求ASL链地址法求ASL

    了解ASL的公式

    查找成功时:ASL = 1 n \frac{1}{n} n1 ∑ i = 1 n C i \sum_{i=1}^{n} C_i i=1nCi   n 为散列表中记录的个数( 不是表的长度 ),   Ci 为查找成功的第 i 个记录所需要的比较次数( 表中空的记录意味着不成功,是不算在里面滴

    查找不成功时:ASL = 1 r \frac{1}{r} r1 ∑ i = 1 n C i \sum_{i=1}^{n} C_i i=1nCi   r 为散列函数取值的个数( 不是表的长度 )。这个就充分解释了为什么散列函数 H(Key) = (key) MOD 11 在计算查找不成功ASL时,r = 11了,是因为这个散列函数的取值为 0~10,可以取11个值,所以 r = 11。   Ci 为 散列函数取值为 i 时,查找失败时第 i 个记录所需要的比较次数( 表中的有些部分,散列函数根本取不到,自然也就不在计算里了

    我想只要把这两个公式看懂,查找成功与不成功的ASL也就自然会求了。下面线性探测法和链地址法我各举一个例子。

    线性探测法求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 线性探测法处理冲突构造所得的哈希表如下:

    地址0123456789key71481130189

    根据公式:查找成功时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时,都是差不多的。首先根据散列函数找到地址,然后从这个地址往后查,一直查到空结束。

    Processed: 0.016, SQL: 9