1. 程式人生 > >Hash表查詢成功和查詢不成功的平均查詢長度

Hash表查詢成功和查詢不成功的平均查詢長度

  Hash表的平均查詢長度包括查詢成功時的平均查詢長度和查詢失敗時的平均查詢長度。
  查詢成功時的平均查詢長度=表中每個元素查詢成功時的比較次數之和/表中元素個數;
查詢不成功時的平均查詢長度相當於在表中查詢元素不成功時的平均比較次數,可以理解為向表中插入某個元素,該元素在每個位置都有可能,然後計算出在每個位置能夠插入時需要比較的次數,再除以表長即為查詢不成功時的平均查詢長度。

  下面舉個例子:
將關鍵字序列{7, 8, 30, 11, 18, 9, 14}雜湊儲存到散列表中。散列表的儲存空間是一個下標從0開始的一維陣列,長度為10,即{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}。雜湊函式為: H(key) = (key * 3) % 7,處理衝突採用線性探測再雜湊法。
求等概率情況下查詢成功和查詢不成功的平均查詢長度。

解:

1 求散列表

H(7) = (7 * 3) % 7 = 0
H(8) = (8 * 3) % 7 = 3
H(30) = 6
H(11) = 5
H(18) = 5
H(9) = 6
H(14) = 0

按關鍵字序列順序依次向雜湊表中填入,發生衝突後按照“線性探測”探測到第一個空位置填入。

address 0 1 2 3 4 5 6 7 8 9
key 7 14 8 11 30 18 9

插入key = 18時,根據H(18) = 5應插在addresss=5的位置,但是address=5已經被key=11佔據了,所以往後挪一位到address=6的位置,但是address=6被key=30佔據了,再往後挪一位到address=7的位置,這個位置是空的,所以key=18就插到這個位置。
插入key = 9時,根據H(9) = 6應插在address=6的位置,但address = 6已經被key = 30佔據,所以需要往後挪一位到address = 7的位置,但是address = 7已經被key = 18佔據,所以再往後挪移到address = 8的位置,這個位置是空的,所以key = 9就插到這個位置。
插入key=14時,根據H(14) = 0應插在address=0的位置,但address=0被key=7佔據,所以往後挪移一位到address=1的位置,這個位置是空的,所以key=14就插到這個位置。

2 求查詢成功的平均查詢長度

查詢7,H(7) = 0,在0的位置,一下子就找到了7,查詢長度為1。
查詢8,H(8) = 3,在3的位置,一下子就找到了8,查詢長度為1。
查詢30,H(30) = 6,在6的位置,一下子就找到了30,查詢長度為1。
查詢11,H(11) = 5,在5的位置,一下子就找到了11,查詢長度為1。
查詢18,H(18) = 5,第一次在5的位置沒有找到18,第二次往後挪移一位到6的位置,仍沒有找到,第三次再往後挪移一位到7的位置,找到了,查詢長度為3。
查詢9,H(9) = 6,第一次在6的位置沒找到9,第二次往後挪移一位到7的位置,仍沒有找到,第三次再往後挪移一位到8的位置,找到了,查詢長度為3.
查詢14,H(14) = 0,第一次在0的位置沒找到14,第二次往後挪移一位到1的位置,找到了,查詢長度為2。

address 0 1 2 3 4 5 6 7 8 9
key 7 14 8 11 30 18 9
length 1 2 1 1 1 3 3

所以,查詢成功的平均查詢長度為(1 + 1 + 1 + 1 + 3 + 3 + 2) / 7 = 12 / 7。

3 求查詢不成功的平均查詢長度

address 0 1 2 3 4 5 6 7 8 9
key 7 14 8 11 30 18 9

查詢不成功,說明要查詢的數字肯定不在上述的散列表中。
因為這裡雜湊函式的模為7,所以要查詢的數只可能位於0~6的位置上。
(1)若要查詢的數key對應的地址為0,有(key * 3) % 7 = 0。
因為key不屬於{7, 8, 30, 11, 18, 9, 14},可設key = 28。
第一次查詢,address = 0時key = 7,不是要找的28,
第二次查詢,往後挪移一位,address = 1時key = 14,不是要找的28;
第三次查詢,往後再挪移一位,address = 2時key為空。可知查詢不成功,否則28應該放在adress = 2的位置上。
結論:查詢3次可知查詢不成功。
(2)若要查詢的數key 對應的地址為1,有(key * 3) % 7 = 1。
因為key不屬於{7, 8, 30, 11, 18, 9, 14},可設key = 5。
第一次address = 1時key = 14,不是要找的5
第二次adress = 2時key為空。可知查詢不成功,否則key = 5應該放在adress=1的位置上。
結論:查詢2次可知查詢不成功。
(3)若要查詢的數key對應的地址為2,有(key * 3) % 7 = 2。
因為key不屬於{7, 8, 30, 11, 18, 9, 14},可設key = 3。
第一次查詢,address = 2時key為空。可知查詢不成功,否則key = 3應該放在address = 2的位置。
結論:查詢1次可知查詢不成功。
(4)若要查詢的數key對應的地址為3,有(key * 3) % 7 = 3。
因為key不屬於{7, 8, 30, 11, 18, 9, 14},可設key = 15。
第一次查詢,address = 3時key = 8,不是要找的15.
第二次查詢,往後挪移一位,address = 4時key為空。可知查詢不成功,否則key = 15會放在address = 4的位置上。
結論:查詢2次可知查詢不成功。
(5)若要查詢的數key對應的地址為4,有(key * 3) % 7 = 4。
因為key不屬於{7, 8, 30, 11, 18, 9, 14},可設key = 6。
第一次查詢,address = 4時key為空。可知查詢不成功,否則key = 6會放在address = 4的位置上。
結論:查詢1次可知查詢不成功。
(6)若要查詢的數key對應的地址為5,有(key * 3) % 7 = 5。
因為key不屬於{7, 8, 30, 11, 18, 9, 14},可設key = 4。
第一次查詢,address = 5時key = 11,不是要找的4.
第二次查詢,往後挪移一位,address = 6時key=30,不是要找的4。
第三次查詢,往後再挪移一位,注意此時address = 0而非address = 7,因為模為7,決定了要查詢的數只可能位於0~6的位置上。address = 0時key = 7,不是要找的4。
第四次查詢,往後再挪移一位,address = 1時key = 14,不是要找的4。
第五次查詢,往後再挪移一位,address = 2時key為空。可知查詢不成功,否則key = 4會放在address = 2的位置上。
結論:查詢5次可知查詢不成功。
(7)若要查詢的數key對應的地址為5,同理可得出結論:查詢4次可知查詢不成功。

綜上,查詢不成功的次數表如下所示

address 0 1 2 3 4 5 6
count 3 2 1 2 1 5 4

所以,查詢不成功的平均查詢長度為(3 + 2 + 1 + 2 + 1 + 5 + 4)/ 7 = 18 / 7