算法导论 11.4 开放寻址法 习题解答

11.4 开放寻址法

11.4-1 考虑用开放寻址法将关键字10,22,31,4,15,28,17,88,59插入到一长度为m = 11的散列表中,辅助散列函数为h’(k) = k。试说明分别用线性探查、二次探查(c1=1,c2=3)和双重散列(h1(k) = k,h2(k) = 1 + (k mod (m - 1)))将这些关键字插入散列表的过程。

线性探查:

1

2

3

4

5

6

7

8

9

0 mod 11

22

22

22

22

22

22

22

22

1 mod 11

88

88

2 mod 11

3 mod 11

4 mod 11

4

4

4

4

4

4

5 mod 11

15

15

15

15

15

6 mod 11

28

28

28

28

7 mod 11

17

17

17

8 mod 11

59

9 mod 11

31

31

31

31

31

31

31

10 mod 11

10

10

10

10

10

10

10

10

10

二次探查:

1

2

3

4

5

6

7

8

9

0 mod 11

22

22

22

22

22

22

22

22

1 mod 11

2 mod 11

88

88

3 mod 11

17

17

17

4 mod 11

4

4

4

4

4

4

5 mod 11

6 mod 11

28

28

28

28

7 mod 11

59

8 mod 11

15

15

15

15

15

9 mod 11

31

31

31

31

31

31

31

10 mod 11

10

10

10

10

10

10

10

10

10

双重散列:

1

2

3

4

5

6

7

8

9

0 mod 11

22

22

22

22

22

22

22

22

1 mod 11

2 mod 11

59

3 mod 11

17

17

17

4 mod 11

4

4

4

4

4

4

5 mod 11

15

15

15

15

15

6 mod 11

28

28

28

28

7 mod 11

88

88

8 mod 11

9 mod 11

31

31

31

31

31

31

31

10 mod 11

10

10

10

10

10

10

10

10

10

11.4-2 试写出HASH-DELETE的伪代码;修改HASH-INSERT,使之能处理特殊值DELETED。

HASH-REMOVE(T, k)

pos := HashSearch(T, k)

if pos != NULL

T[pos] := DEL

return pos

HASH-INSERT(T, k)

    i = 0

    repeat

        j = h(k, i)

        if T[j] == NIL or T[j] == DEL

            T[j] = k

            return j

        else i = i + 1

    until i == m

    return "overflow"

11.4-3 考虑一个采用均匀散列的开放寻址散列表。当装载因子为3/4和7/8时,试分别给出一次不成功查找和一次成功查找的探查期望数上界。

α=3/4:

不成功:1 / (1−3/4) = 4 次

成功:1 / (3/4)​* ln (1/(1−3/4)) ≈ 1.848次

α=7/8:

不成功:1 / (1−7/8) = 8 次

成功:1 / (7/8)​* ln (1/(1−7/8)) ≈ 2.377次

11.4-4 假设采用双重散列来解决冲突,即所有的散列函数为h(k,i) = (h1(k) + i * h2(k)) mod m。试证明:如果对某个关键字k,m和h2(k)有最大公约数d >= 1,则在对关键字k的一次不成功查找中,在返回槽h1(k)之前,要检查散列表中第(1/d)个元素。于是,当d = 1时,m与h2(k)互素,查找操作可能要检查整个散列表。

哈希冲突的处理方式: 当插入一个关键字时,如果发生哈希冲突,就意味着两个关键字被映射到了同一个槽位。为了解决这个问题,我们使用了双重散列,即尝试将关键字插入到下一个可能的槽位。

最大公约数 d 的作用: 如果哈希表的大小 m 和 h2(k) 有一个大于等于1的最大公约数 d,那么在查找时,我们不仅仅需要考虑 h1(k) 的位置,还需要检查哈希表中的另一个位置。

为什么要检查另一个位置: 这是因为在双重散列中,我们通过累加h2(k) 来寻找下一个可能的槽位。当 d>1 时,这个累加可能会导致我们错过一个本应插入的位置。因此,我们在查找过程中需要额外检查哈希表中的一个位置,以确保没有漏掉可能的插入位置。

特殊情况 d=1: 当 d=1 时,也就是说,哈希表的大小 m 与 h2(k) 互素(没有公约数),我们可能需要检查整个哈希表。这是因为在这种情况下,我们无法通过简单的检查一个特定位置来确保不会错过插入位置,所以可能需要遍历整个哈希表。

在这个问题中,我们考虑了h2(k) = d*c1,其中 m和h2(k)有最大公约数d,m = d*c2

假设 d>1,即 m 与 h2(k) 有公约数。

m = d*c2

h2(k) = d*c1

在探测 1/d 的表项时,即 i = d/m​,我们有:

h(k,m/d)=(h1(k) + m/d * h2(k)) mod m

h(k,m/d)=(h1(k) + m/d * d * c1) mod (d * c2)

简化后:

h(k,m/d)=(h1(k)+ m * c1) mod (d * c2)

由于 m=d*c2,我们得到:

h(k,m/d)=(h1(k)+ d * c2 * c1) mod (d * c2)

这里我们可以看到d * c2 * c1是d*c2的倍数,所以有:

h(k,m/d)=h1(k) mod m

在探测了 1/d 的表项之后,我们实际上检查的表项等同于h1(k) 对 m 取模后的结果。这确保了我们不会错过可能的插入位置,因为在双重散列的过程中,我们通过累加 h2(k) 来寻找下一个可能的槽位。在这个特定的情况下,我们通过检查1/d 的表项,确保了在h2(k) 的整数倍上进行探测。

11.4-5 考虑一个装载因子为α的开放寻址散列表。找出一个非零的α值,使得一次不成功查找的探查期望数是一次成功查找的探查期望数的2倍。这两个探查期望数可以使用定理11.6和定理11.8中给定的上界。

1 / (1 - α) = 2 * 1 / α* ln(1/(1-α))

α=0.71533

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值