算法导论第十一章----11.1.1-11.1.4

http://test.scripts.psu.edu/users/d/j/djh300/cmpsc465/notes-4985903869437/solutions-to-some-homework-exercises-as-shared-with-students/3-solutions-clrs-11.pdf

Exercise 11.1-1
Suppose  that  a  dynamic  set Sis represented by a direct-address  table Tof length m.  Describe  a  procedure  that  finds  the 
maximum element of S. What is the worst-case performance of your procedure?
Solution:
We can do a linear search to find the maximum element in Sas follows:
Pre-condition: table T is not empty; m ∈  Z+, m ≥1.
Post-condition: FCTVAL == maximum value of dynamic set stored in T.

FindMax (T, m)
{
    max= −∞
    for i=1 to m
    {
        if T[i] != NIL && max< T[i]
        max= T[i]
    }
    return max
}

In the worst-case searching the entire table is needed. Thus the procedure must take O (m) time.

http://www.roading.org//algorithm/introductiontoalgorithm/solution-of-clrs-11-1-exercises.html

Exercises 11.1-2

bit vector is simply an array of bits (0's and 1's). A bit vector of length mtakes much less space than an array of m pointers. Describe how to use a bit vector to Represent a Dynamic Set of Distinct Elements with no Satellite Data. Dictionary Operations Should Run in O(1) Time.

Solution(I get the result from Rip’s blog, The original text is here for ease of reference.):

Using a bit vector of length m, as our direct-address table to represent the dynamic set.Here m bits tags m slots of the table. The elements in the dynamic set is stored in the direct-address table itself. If slot k is allocated, bit k is 0. If slot k contains no element, bit k is 1.

Bit Vector

The free-space list is often implemented as a bit map or bit vector. If a block is free, the bit is 1. If a block is allocated, the bit is 0. Assume the following blocks are allocated, the rest free: 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 17, 18, 25, 27 .The free-space bit map would be: 0011110011111100011000000111000000…

Adavantages of this approach include: 
· Relatively simple 
· Efficient to find the first free blocks or n consecutive free blocks on the disk.

Bit maps are useful only when it can be kept in main memory. But, as disks get larger, this is hard to do. 1.3 gigabyte disk with 512 byte blocks would need a bit map of over 310k to track its free blocks. Clustering the blocks in intervals of foul reduces this number to 78k per disk.

Exercises 11.1-3

Suggest how to implement a direct-address table in which the keys of stored elements do not need to be distinct and the elements can have satellite data. All three dictionary operations (INSERT, DELETE, and SEARCH) should run in O(1) time. (Don't forget that DELETE takes as an argument a pointer to an object to be deleted, not a key.)

Solution:可以直接用链表来解决碰撞问题。对于搜索的话可以返回链表的指针,根据题 目的条件来看,对于两个用户提供的两个key相同的object我们是无法区分的,因此只能返回 一组key相同的objecet让用户用自己的方法来区分。

Exercises 11.1-4

We wish to implement a dictionary by using direct addressing on a huge array. At the start, the array entries may contain garbage, and initializing the entire array is impractical because of its size. Describe a scheme for implementing a direct-address dictionary on a huge array. Each stored object should use O(1) space; the operations SEARCH, INSERT, and DELETE should take O(1) time each; and the initialization of the data structure should take O(1) time. (Hint:Use an additional stack, whose size is the number of keys actually stored in the dictionary, to help determine whether a given entry in the huge array is valid or not.)

Solution:一直没想出好的办法来解决这个问题,今天看《算法导论教师手册》有这个题 的解答。觉得它的数据结构的思路比较巧妙:字典中每个元素带有一个索引,表示关于该元 素的的key存储在辅助栈中的位置。而辅助栈用数组实现,因此可以随机访问。辅助栈中存储 所有存在于字典中的元素的key ,于是形成了一个所谓validating cycle。要判断从字典中 直接读取到的元素是不是需要的数据,只需要取出该元素中的索引,判断这个索引是否有效 (大于栈底而小于栈顶),然后通过索引获取栈中的key ,与自己需要的元素的key比较看是 否相等即可以。相等表示该数据是要找的数据,否则不是。显而易见,通过这个数据结构模 型来进行SEARCH, INSERT都为O(1)。至于DELETE 操作,需要将被删除的数据在栈中的key 与栈顶存储的key交换后再删除,同样可以达到O(1),要注意的是删除过程中,需要更新与 原栈顶中key相关元素的索引。


https://sites.google.com/site/clrssolutions/home/chapter11

11.1-3

需要假设卫星数据也能组织为direct-access table。二级direct-access table的各个操作时间仍为O(1)。

11.1-4&
需要一个大小为Huge中元素数量的数组A。Huge中存储数据的元素位置会在A中记录。在Huge中的元素不仅存储了数据本身,还存储了一个A的索引i,A[i]的内容就是Huge中这个元素的key值。A[0]存储Huge中元素的数量。
初始时Huge为空,A[0]=0。通过Huge中元素的索引i,在A中查找相应位置判断Huge中该处是否存在元素。
Huge=[[None,None]]*10 #a huge array containing garbage
A=[0]*5
def insert(k,d):#the element is key[ele]=k, satilite_data[ele]=d
    A[0]+=1
    A[A[0]]=k
    Huge[k]=[A[0],d]
def search(k):
    i,data=Huge[k]
    if A[i]!=k:
        raise Exception('No such element')
    else:
        return data
def delete(k):
    i,data=Huge[k]
    Huge[k]=(None,None)
    Huge[A[A[0]]][0]=i#exchange i with the last one
    A[i],A[A[0]]=A[A[0]],A[i]
    A[0]-=1


算法导论教师手册第三版.pdf
Solution to Exercise 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[S.top]
S'[T[k]] = S'[S.top]
T[S[T[k]]] = T[k]
T[k] = 0
S.top = S.top - 1

Each of these operations—initialization, SEARCH, I NSERT, and D ELETE—takes O(1)  time.

你可能感兴趣的:(算法导论第十一章----11.1.1-11.1.4)