算法导论答案 第11章:散列表

本文深入探讨了散列表与直接寻址表的关键操作,包括初始化、搜索、插入和删除,详细解释了它们的时间复杂度与实现细节。特别关注了散列表在不同场景下的性能表现,并通过实例演示了如何使用直接寻址表解决碰撞问题。同时,介绍了散列函数的构造方法,以及开放寻址法在解决冲突时的不同策略与效果评估。

11.1 直接寻址表


11.1-1

findmax(T,m)
{
	max=T[0];
	for i=1 to m-1
	{
		if T[i]!=NIL && T[i]>max
		max=T[i]
	}
	return max
}
最坏情况下的运行时间为O(m)

11.1-2

如果位向量的第k位有元素则设为1,否则设为0



11.1-3

用链表解决碰撞问题

11.1-4

We denote the huge array by T and, taking the hint from the book, we also have a
stack implemented by an array S . The size of S equals the number of keys actually
stored, so that S should be allocated at the dictionary’s maximum size. The stack
has an attribute S: top, so that only entries S[1.. S.top] are valid.
The idea of this scheme is that entries of T and S validate each other. If key k is
actually stored in T , then T[k] contains the index, say j , of a valid entry in S , and
S[j] contains the value k. Let us call this situation, in which 1 ≤ T[k] ≤ S.top,
S[T[k]] = k, and T[S[j]] = j , a validating cycle.
Assuming that we also need to store pointers to objects in our direct-address table,
we can store them in an array that is parallel to either T or S . Since S is smaller
than T , we’ll use an array S', allocated to be the same size as S , for these pointers.
Thus, if the dictionary contains an object x with key k, then there is a validating
cycle and S[T[k]] points to x .
The operations on the dictionary work as follows:

  • Initialization: Simply set S.top = 0, so that there are no valid entries in the stack.
  • SEARCH: Given key k, we check whether we have a validating cycle, i.e., whether 1 ≤ T[k] ≤ S.top and S[T[k]] = k. If so, we return S'[T[k]], and otherwise we return NIL
  • INSERT: To insert object x with key k, assuming that this object is not already in the dictionary, we increment S.top, set S[S.top] = k, set S'[S.top] = x , and set T[k] = S.top.
  • DELETE: To delete object x with key k, assuming that this object is in the dictionary, we need to break the validating cycle. The trick is to also ensure that we don’t leave a “hole” in the stack, and we solve this problem by moving the top entry of the stack into the position that we are vacating—and then fixing up that entry’s validating cycle. That is, we execute the following sequence of assignments:

S[T[k]]S[top[S]]
S'[T[k]] ← S'[top[S]]

T[S[T[k]]]T[k]

T[k]0

top[S]top[S]1

Each of these operations---initialization, SEARCH, INSERT, and DELETE---takes
O(1)time.
实现:http://blog.youkuaiyun.com/mishifangxiangdefeng/article/details/7709567


11.2 散列表


11.2-1


11.2-3

成功查找:Θ(1 + α)    The element we search for is equally likely to be any of the elements in the hash table.

不成功查找:1/2 of the original running time, but still Θ(1 + α), if we simply assume that the probability thatone element's value falls between two consecutive elements in the hash slot is uniformly distributed.

        This is because the value of the element we search for is equally likely to fall between any consecutive elements in the hash slot, and oncewe find a larger value, we can stop searching. Thus, the running time for unsuccessful searches is a half of the originalrunning time.
插入:Θ(1 + α), compared to the original running time of Θ(1 ).

       This is because we need to find the right location instead of the head to insert the element so that the list remains sorted.

删除:Θ(1 + α), same as successful searches.


11.2-4


11.2-5

鸽笼原理:Hash U中所有元素,则必有一个slot的元素数量大于n。若不然,m个slots共有小于等于nm个元素,矛盾

11.3 散列函数

11.3-1

先将给定元素的散列值与链表中的散列值比较,如果相等,再比较关键字

11.3-2

从字符串的低位开始,每处理一个字符,就将得到的数取一次模,这样就可以只利用常数个机器字了

11.3-3

11.3-4

h(61)=700

h(62)=318

h(63)=936

h(64)=554

h(65)=172


11.3-5

11.3-6*


11.4 开放寻址法

11.4-1

 线性探查 22 88 0 0 4 15 28 17 59 31 10

 二次探查 22 0 88 17 4 0 28 59 15 31 10

 双重散列 22 0 59 17 4 15 28 88 0 31 10


11.4-2

 

HASH-DELETE(T,i)
{
	
		if T[i]!=NIL
			then T[i]=DELETED 
		else
			return false
	
			
}

HASH-INSERT(T,k)
{
	i=0
	repeat j=h(k,i)
		if T[j]=NIL or DELETED
			then T[j]=k 
			return j
		else 
			i=i+1
	until i=m
	error "hash table overflow"
}

11.4-3 *

11.4-4

定理11.6及11.8

不成功的查找:1/(1-a)     1/(1-3/4)=4次   1/(1-7/8)=8次

成功的查找:  (1/a)ln(1/(1-a))   (1/(3/4))ln(1/(1-3/4)) =1.848   (1/(7/8))ln(1/(1-7/8))=2.377

11.4-5*

1/(1-a)=2*(1/a)ln(1/(1-a))   解得a≈0.715

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值