算法导论程序26--开放寻址法(Python)

来源:互联网 发布:淘宝耳机店推荐 编辑:程序博客网 时间:2024/06/05 02:52

在开放寻址法(open addressing)中,所有元素都存放在散列表中。也就是说,每个表项或包含动态集合的一个元素,或包含NIL。当查找某个元素时,要系统地检查所有的表项,直到找到所需的元素,或最终查明该元素不在表中。开放寻址法中,散列表可能会被填满,以至于不能插入任何新的元素,该方法导致的一个结果是装载因子a绝对不会超过1。

为了使用开放寻址法插入一个元素,需要连续地检查散列表,或称为探查(probe),直到找到一个空槽来放置待插入的关键字为止。

检查的顺序不一定是0,1,...,m-1(这种顺序下的查找时间为O(n)),而是依赖于待插入的关键字。对每一个关键字k,使用开放寻址法的探查序列(probe squence)

<h(k,0),h(k,1),...,h(k,m-1)>。

有三种技术常用来计算开放寻址法中的探查序列:线性探查、二次探查和双重探查。

这三种技术中,双重散列产生的探查序列数最多,似乎能给出最好的结果。


双重散列:

采用的散列函数:h(k,i)=(h1(k)+i*h2(k))mod m

其中h1和h2均为辅助散列函数。

初始探查位置T[h1(k)],后续的探查位置是前一个位置加上偏移量h2(k),然后再模m。

比如h1(k)=k mod m,h2(k)=1+(k mod m')其中m'略小于m(比如,m-1)


class open_address_hash:    def __init__(self,T=[],size=0):        if len(T)==0:            self.T=[None for i in range(size)]        else:            self.T=T        self.size=size    def hash_insert(self,k):        i=0             while i<self.size:            j=self.hash_h1_h2(k,i)            if self.T[j] == None:                self.T[j]=k                return j            else:                i+=1        return "hash table overflow"    def hash_search(self,k):        i=0        j=self.hash_h1_h2(k,i)        while self.T[j]!=None and i<self.size:            j=self.hash_h1_h2(k,i)            if self.T[j]==k:                return j            else:                i+=1        return None    def hash_h1_h2(self,k,i):        return ((k%self.size+i*(1+k%(self.size-2))))%self.size    
运行:

>>> T=[]>>> oah=open_address_hash(T,13)>>> oah.hash_insert(79)1>>> oah.hash_insert(69)4>>> oah.hash_insert(98)7>>> oah.hash_insert(14)5>>> oah.hash_search(50)>>> oah.hash_search(14)5>>> 
其中,散列表的大小为13。